battmanz
battmanz

Reputation: 2296

Pass parameter to service constructor

Let's suppose I have this Angular 2 service:

@Injectable()
class Demo {
    constructor(private instanceSpecificString: string) {
    }
}

Notice that its constructor accepts an instance-specific string. What I mean by that is that I want to instantiate this service multiple times and, each time it gets instantiated, I want to pass it a different string based on the context in which the service is instantiated.

How do I do that?

P.S. string is used as an example, but the parameter could easily be of type number, or boolean or even some kind of configuration object.

Upvotes: 20

Views: 19030

Answers (2)

Jeremy
Jeremy

Reputation: 3809

Because the service is declared a injectable (@Injectable() annotation) it is a singleton. So instead just remove the annotation from the top of your service to remove that restriction.

This is not necessarily best practices but it will work and compile with AOT enabled.

Example:

Change this service:

@Injectable()
export class BaseSocket extends Socket {   
  protected constructor(
    private baseConfig:SocketIoConfig
    ...   
  ) {
    super();   
  } 
}

Into this:

export class BaseSocket extends Socket {
  protected constructor(
    private baseConfig:SocketIoConfig
    ...
  ) {
     super();
  }
}

Upvotes: 1

awiseman
awiseman

Reputation: 5704

The value that gets passed to your service will be determined by the injector that's instantiating it. You might be able to do this in one of your component definitions:

@Component({
    ...
    providers: [
        provide(string, {useValue: "someSpecificValue"})
    ]
})

However, this has the problem that you're defining a provider for the string token and that could lead to maintainability issues.

It would probably be a better pattern to define some config model for your service:

class DemoConfig {
    instanceSpecificString: string;
}

And then you could create an instance of that to pass to your service.

let config = { instanceSpecificString: "someSpecificValue" }

@Component({
    ...
    providers: [
        provide(DemoConfig, {useExisting: config})
    ]
})

Hope this is helpful. I haven't tried this myself; the services I use in my application are singletons. Here is the reference that I was using:

https://angular.io/docs/ts/latest/api/core/index/provide-function.html

Upvotes: 4

Related Questions