How can I pass an argument to a provider constructor in Ionic2 / Angular2?

10,842

Solution 1

You have to change the way, how you define the provider:

@NgModule({
  ...
  providers: [
    Http,
    {
      provide: AuthService,
      useFactory: getAuthService,
      deps: [Http]
    }
  ]
})

The last piece is the factory function:

export function getAuthService(http: Http): LoggingService {
  return new AuthService(http);
}

See also Migrating to Ionic 2 RC 0 - ngc fails

Solution 2

I had the same issue & Markus put me on the right track but here's what I needed to do to get going (see also "Factory Providers" under Angular docs Dependency Injection):

Make the constructor parameter in the injected service optional. This alone is not enough (http was undefined at runtime)

constructor(public http?: Http){}

Create a service provider class SomeServiceProvider.ts:

import { Http } from '@angular/http';
import { SomeService } from 'some-service';

export function someServiceFactory(http: Http){
  return new SomeService(http);
}

export let SomeServiceProvider =
  { provide: SomeService,
    useFactory: someServiceFactory,
    deps: [ Http ]
  };

In the root app.component.ts, add the service provider:

@Component({
  ...
  providers: [ SomeServiceProvider ]
})

Remove the service from the @NgModule providers in app.module.ts.

To use the service in components, get it from Injector rather than injecting the service:

import { Component, Injector } from '@angular/core';
import { SomeService } from 'some-service';

@Component({
  ...
})

export class MyComponent{
  someService: SomeService = this.injector.get(SomeService);

  constructor(private injector: Injector) {}

}
Share:
10,842
Andreas Gassmann
Author by

Andreas Gassmann

Updated on July 19, 2022

Comments

  • Andreas Gassmann
    Andreas Gassmann almost 2 years

    I am trying to port my Ionic2.beta11 App to the new Ionic2.rc0 release. Most things were pretty straight forward, but I have a problem with the AoT compiler.

    I have an AuthService:

    @Injectable()
    export class AuthService {
      constructor(@Inject(Http) http: Http) {
        this.http = http;
      }
      ...
    }
    

    I'm injecting it into my app in the src/app/app.module.ts file:

    @NgModule({
      declarations: [
        MyApp,
        ...
      ],
      imports: [
        IonicModule.forRoot(MyApp)
      ],
      bootstrap: [IonicApp],
      entryComponents: [
        MyApp,
        ...
      ],
      providers: [
        AuthService
      ]
    })
    

    Everything works fine when running ionic serve, but when I try to build it I get the following error:

    ngc error: Error: Error at .../.tmp/app/app.module.ngfactory.ts:397:78: Supplied parameters do not match any signature of call target.
    

    Lines 396 - 399:

    get _AuthService_74():import44.AuthService {
      if ((this.__AuthService_74 == (null as any))) { (this.__AuthService_74 = new import44.AuthService()); }
      return this.__AuthService_74;
    }
    

    The problem is that new import44.AuthService() expects an argument of type http.

    The interesting thing is that everything works fine when I manually replace constructor(http: Http) with constructor() in the definition file.

    I read through all the StackOverflow answers I could find, but none of the solutions solved my problem.

    Do I need to change the constructor in the AuthService or the way how I inject it into my app? Thank you for your help.