Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

angular

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.

like image 536
Eugene Kirin Avatar asked Mar 21 '26 02:03

Eugene Kirin


1 Answers

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 InjectionTokens 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) {}
}
like image 65
Aluan Haddad Avatar answered Mar 22 '26 16:03

Aluan Haddad