Angular 2 - Using Shared Service
Asked Answered
S

3

11

Looks like shared services is the best practice to solve many situations such as communication among components or as replacement of the old $rootscope concept of angular 1. I'm trying to create mine, but it's not working. Any help ? ty !!!

app.component.ts

import {Component} from 'angular2/core';
import {OtherComponent} from './other.component';
import {SharedService} from './services/shared.service';
@Component({
selector: 'my-app',
providers: [SharedService],
directives: [OtherComponent],
template: `
    <button (click)="setSharedValue()">Add value to Shared Service</button>
    <br><br>
    <other></other>
`
})
export class AppComponent { 
data: string = 'Testing data';
setSharedValue(){
    this._sharedService.insertData(this.data);
    this.data = '';
    console.log('Data sent');
}
constructor(private _sharedService: SharedService){}
}

other.component.ts

import {Component, OnInit} from "angular2/core";
import {SharedService} from './services/shared.service';
@Component({
selector : "other",
providers : [SharedService],
template : `
I'm the other component. The shared data is: {{data}}
`,
})
export class OtherComponent implements OnInit{
data: string[] = [];
constructor(private _sharedService: SharedService){}
ngOnInit():any {
    this.data = this._sharedService.dataArray;
}
}
Saire answered 27/3, 2016 at 19:3 Comment(0)
D
9

Most of time, you need to define your shared service when bootstrapping your application:

bootstrap(AppComponent, [ SharedService ]);

and not defining it again within the providers attribute of your components. This way you will have a single instance of the service for the whole application.


In your case, since OtherComponent is a sub component of your AppComponent one, simply remove the providers attribute like this:

@Component({
  selector : "other",
  // providers : [SharedService], <----
  template : `
    I'm the other component. The shared data is: {{data}}
  `,
})
export class OtherComponent implements OnInit{
  (...)
}

This way they will shared the same instance of the service for both components. OtherComponent will use the one from the parent component (AppComponent).

This is because of the "hierarchical injectors" feature of Angular2. For more details, see this question:

Daman answered 27/3, 2016 at 19:27 Comment(3)
You're too fast :P Here's a working plunker: plnkr.co/edit/HX3LT9RaJD6ki3vpa1aW. Since the data is stored into an array, you need to also iterate over the array to display the separate pieces of info you storeMadonnamadora
Correct me if I'm wrong, but it looks like the bootstrap has changed in Angular 2 final. Do you guys have any idea how can I adapt the solution you provided? thanks!Nessa
Indeed, this provided solution does not seems to work on latest version of Angular 5. Bootstrap syntax has been also changed if you try that it will say Service cannot be used as an entry componentWinder
P
4

You need to add a global provider in your module, then you dont need to add this provider in each component. try this

app.module.ts

@NgModule({
    imports: [BrowserModule, FormsModule, HttpModule],
    declarations: [AppComponent, LoginComponent, InComponent],
    providers: [LoginService],
    bootstrap: [AppComponent]
})

app.component.ts

@Component({
    moduleId: module.id,
    selector: 'app',
    templateUrl: './app.component.html'
})
export class AppComponent {
    constructor(public loginService: LoginService) {

    }
}

login.component.ts

@Component({
    moduleId: module.id,
    selector: 'login',
    templateUrl: './login.component.html'
})
export class LoginComponent {

    constructor(public loginService: LoginService) {

    }
}

I hope this work for you.

Parliamentarian answered 14/10, 2016 at 1:43 Comment(0)
W
1

In addition to your requirement and its solution, you can consider using Facade + Shared Services. I have a small project here: https://github.com/cmandamiento/angular-architecture-base

Wornout answered 14/5, 2020 at 17:40 Comment(1)
Welcome to Stack Overflow. I suggest you add a small example how to use Facade.Impalpable

© 2022 - 2024 — McMap. All rights reserved.