简体   繁体   中英

Angular 7 - build --prod failed with error: Can't resolve all parameters for

I use Angular: 7.2.10 and when I try to build project for production with command:

ng b --prod

I got error

ERROR in : Can't resolve all parameters for ApiService in ...

I have service with a constructor with 3 params:

constructor(api: string, private _http: HttpClient, private httpUtils: HttpUtilsService) {
    this.api = `${api}/api`;        
  }

Which instantiates by factory defined at app.module.ts:

{      
      provide: ApiService,
      useFactory: apiHost,
      deps: [Store, HttpClient, HttpUtilsService]
    }

apiHost

export function apiHost(store: Store<RemoteConfig>, http: HttpClient, httpUtils: HttpUtilsService) {
  let item: string = localStorage.getItem(environment.apiHost);

  //store.pipe(select(backendApiHost), take(1)).subscribe(api => item = api); // Todo not always read val!
  //console.log('ss: ' + item);
  return new ApiService(item, http, httpUtils);
}

When I use ng build it works successfully.

Dependencies are implicitly resolved by examining the metadata emitted by the compiler. This metadata is derived from the types of the parameters.

At runtime, the angular injector inspects that information to determine which dependencies to inject. Specifically, it looks for a registered provider for each corresponding parameter.

Since you haven't registered a provider that maps to the metadata emitted for a parameter of type string the lookup fails and you receive an error. You could register a provider for that type but it would not be wise to do so given just how broadly strings are used.

However, Angular's dependency injection facilities are not limited to this implicit resolution. Using a combination of the Inject decorator and InjectionToken s you can achieve what you wish.

api-token.ts

import {InjectionToken} from '@angular/core';

export const apiToken = new InjectionToken('api', {
  providedIn: 'root',
  value: 'myapi'
});

Now you can use this token to request that this dependency is resolved for a specific parameter.

data.service.ts

import {Inject, Injectable} from '@angular/core';

import {apiToken} from './api-token';

@Injectable({providedIn: 'root'})
export class DataService {
   constructor(@Inject(apiToken) api: string) {}
}

Angular can't find a provider for api: string . In fact, you do not inject ApiService, you create it in the code here: return new ApiService(item, http, httpUtils) , so you don't need to define it in providers.

i suggest you to remove the api variable from the constructor, pass it on the class methods, use the constructor only to pass injection.


    constructor(public _http: HttpClient) { }

getApi(api: string) {
    this._http.get(api).toPromise()
}

then extends your api service and pass the uri in the parameter, i suggest you let _http public too, the api host cannot see the private http and these typing can fail a build prod

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM