0

First of all, I have a Context class and aSingleton. I would like Context to give an instance of Http and Events to Singleton.

import { Http } from 'angular2/http';
import { Injectable, Injector, Provider, provide } from 'angular2/core';
import { Events } from 'ionic-angular';

@Injectable()
export class Context{
    constructor(private http: Http, private events: Events){}
}

export class Singleton{
    private static INSTANCE: Singleton;

    private context: Context;

    constructor(){
        if(Singleton.INSTANCE){
            throw new Error();
        }
        let injector = Injector.resolveAndCreate([
            Https,
            Events
        ])
        this.context = injector.get(Context);
    }

}

However, when I compile and inspect. An error with "No provider" was raised. Thus, how could I add a provider?

Secondly, how could I use http and events in Singleton? I suppose this.http in Singleton doesn't work.

Zhipeng YANG
  • 797
  • 9
  • 18

2 Answers2

1

You need to set Context as well:

let injector = Injector.resolveAndCreate([
        Https,
        Events,
        Context // <-------
    ])
    this.context = injector.get(Context);
}

That being said, Angular2 will keep a single instance per provider and you don't need to implicitly leverage the Injector class.

You don't need a SINGLETON class. You can inject directly a Context instance into another component or service:

@Component({
  (...)
  providers: [ Context ]
})
export class SomeComponent {
  constructor(private context:Context) {
  }
}

By setting the provider in the providers attribute of a component, context will be a singleton for the component, its sub components and all services they will call.

If you want to define a singleton for the whole application, specify the provider when bootstrapping your application:

bootstrap(App, [ Context ]);

Don't forget to remove if from the providers attribute of components.

You also need to be aware that injectors are linked to components. For more details, this question you help you:

Edit

To use the Http class into your Singleton class, you need to define the HTTP_PROVIDERS instead of the Http one:

let injector = Injector.resolveAndCreate([
        HTTP_PROVIDERS, // <-------
        Events,
        Context
    ])
    this.context = injector.get(Context);
    this.http = injector.get(Http); // <-------
}
Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • Well, we use singleton at work. So in fact, it's not because I want to inject then I use singleton. It's I need to use singleton then I need to inject. – Zhipeng YANG Jun 02 '16 at 09:13
  • Plus, how can I use `http` in the class `Singleton`? Should I declare `http` and `events` as public in Context? – Zhipeng YANG Jun 02 '16 at 09:14
  • Just a small question: I've tried to use injector and it works. However, if I didn't make any mistake, the instance of `Events` is not the same as `Events` that passed by constructor. Is that normal? – Zhipeng YANG Jun 02 '16 at 15:17
0

update

export class Singleton{
    private static INSTANCE: Singleton;

    constructor(private context:Context){
      console.log(context.http);
      console.log(context.events);
    }
}

original

    let injector = Injector.resolveAndCreate([
        Https,
        Events
    ])

creates a new and independent injector that only knows the providers Https and `Events.

You need to inject Angulars injector in order to be able to get instances from providers provided for example in bootstrap(...)

constructor(private injector:Injector){
  this.context = injector.get(Context);
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567