How to inject a provider in Angular 2 service from action?
In your action you can inject the Http in constructor and pass it into the service instance. Something like
export default class SampleAction {
private _projectService;
constructor(@Inject(Http) http: Http) {
this._sampleService = new SampleService(http);
}
}
Inject provider into another provider
In fact, injectors can be only configured at the component level or when bootstrapping the application.
When you set providers at the component level, every classes involved in the processing will have a access to these providers: sub components, services. But you can't configure providers for services themselves.
If you configure providers at the bootstrap level (when calling the bootstrap
function), all elements in the application will be able to use these providers.
In fact, dependency injector of Angular2 leverages hierarchical injectors. This means that if the provider isn't found at a level, it will be look for in the level above and so on.
Here is an overview of all these elements and there relations:
Application
(providers defined in bootstrap)
|
AppComponent
(providers defined in the providers attribute)
|
ChildComponent
(providers defined in the providers attribute)
getData() --- Service1 --- Service2
To be able to use Service2
in Service1
, the corresponding provider must be found in the providers tree.
In such application, we have three injectors:
- The application injector that can be configured using the second parameter of the
bootstrap
function - The
AppComponent
injector that can be configured using theproviders
attribute of this component. It can "see" elements defined in the application injector. This means if a provider isn't found in this provider, it will be automatically look for into this parent injector. If not found in the latter, a "provider not found" error will be thrown. - The
ChildComponent
injector that will follow the same rules than theAppComponent
one. To inject elements involved in the injection chain executed forr the component, providers will be looked for first in this injector, then in theAppComponent
one and finally in the application one.
This answer could give you more details about the hierarchical injectors:
- What's the best way to inject one service into another in angular 2 (Beta)?
How to share same instance of domain model in Angular2, and propagate changes?
For this you need to add your Shell service when bootstrapping your application:
bootstrap(AppComponent, [ Shell ]);
And remove it from all viewProviders attribute of your components:
@Component({
selector: 'my-app',
providers: [TemplateRef],
templateUrl: './angular/app/Index.html',
directives: [ROUTER_DIRECTIVES, NgIf],
// viewProviders: [Shell] <-------
})
It's because of the way the "hierarchical injectors" feature of Angular2 works. For more details you could have a look at this question:
- What's the best way to inject one service into another in angular 2 (Beta)?
How to inject new instance of same component in Angular2
Angular2 doesn't allow to bootstrap the same component twice in an HTML page.
This is however possible to bootstrap different application components if you want in a same HTML page.
See this documentation for more details:
- https://angular.io/docs/ts/latest/api/platform/browser/bootstrap-function.html (Section "Bootstrapping Multiple Applications")
Edit
Regarding your second question, you need to be aware that @Component
and @Injectable
are decorators. They are responsible to "wrap" target instances and allow dependency injections by providing right dependency instances in constructor based on configured metadata.
Regarding hierarchical injectors, you could have a look at this link:
- What's the best way to inject one service into another in angular 2 (Beta)?
Angular2 - Share data between components using services
You define it within your two components. So the service isn't shared. You have one instance for the AppComponent
component and another one for the Grid
component.
@Component({
selector: 'my-app',
templateUrl: 'app/templates/app.html',
directives: [Grid],
providers: [ConfigService]
})
export class AppComponent {
(...)
}
The quick solution is to remove the providers
attribute to your Grid component... This way the service instance will be shared by the AppComponent
and its children components.
The other solution is to register the corresponding provider within the bootstrap
function. In this case, the instance will be shared by the whole application.
bootstrap(AppComponent, [ ConfigService ]);
To understand why you need to do that, you need to be aware of the "hierarchical injectors" feature of Angular2. Following links could be useful:
- What's the best way to inject one service into another in angular 2 (Beta)?
- https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html
How can I call a service provider within another one - angularjs2
Just define this service when bootstrapping your application and inject it in the service you want to use it:
bootstrap(AppComponent, [ CardService , ProductService ]);
In the service:
@Injectable()
export class CardService {
constructor(private _productService: ProductService) {
}
}
Don't forget to specify the @Injectable decorator.
This question could give more details on how dependency injection, hierarchical injectors and injection into services work:
- What's the best way to inject one service into another in angular 2 (Beta)?
Angular 2 Component Interaction via a service
If you add the "shared" service to providers
of each component
@Component({
selector: 'dir2',
template: '{{field}}',
providers: [DirService]
})
then for each component a new instance is maintained.
To get a shared service you either add it only in bootstrap(AppComponent, [DirService])
or one common ancestor of the components and directives that defines the root component and the scope of the shared service.
This way every descendant gets the same instance.
Plunker example
See also
- AngularJs 2 - multiple instance of service created
- How to use Dependency Injection (DI) correctly in Angular2?
Related Topics
Chained Promises Not Passing on Rejection
How to Check If File Exists in Jquery or Pure JavaScript
Why Is Null an Object and What's the Difference Between Null and Undefined
Sending Command Line Arguments to Npm Script
Why Do You Need to Invoke an Anonymous Function on the Same Line
Get the Real Width and Height of an Image With JavaScript? (In Safari/Chrome)
How to Get Element by Class in JavaScript
Settimeout Calls Function Immediately Instead of After Delay
Changing the Image Source Using Jquery
Find an Element in Dom Based on an Attribute Value
Sum JavaScript Object Propertya Values With the Same Object Propertyb in an Array of Objects
Static Variables in JavaScript
How to Detect Internet Speed in JavaScript