Search code examples
angularangular2-services

Get and update a string through a service in Angular 2


I'm trying to better understand services by means of a very simple application which gets and updates the value of string within a service and displays it in a component.

Here's the service:

import {Injectable} from 'angular2/core';

@Injectable()
export class SharedService {
  dataString: string;

  insertData(data) {
    this.dataString = data
  }
}

Here's the main 'app' component:

import {Component}      from 'angular2/core';
import {OtherComponent} from './other';
import {SharedService}  from'./shared.service';

@Component({
  selector: 'my-app',
  providers: [SharedService],
  directives: [OtherComponent],
  template: `
    <input type="text" #someValue>
    <button (click)="setSharedValue(someValue.value)">Change value in shared service</button>
    <br><br>
    <other></other>
  `
})
export class AppComponent { 
  constructor(private _sharedService: SharedService){}

  setSharedValue(value){
    this._sharedService.insertData(value);
  }

}

...and here's the 'other' component:

import {Component, OnInit} from 'angular2/core';
import {SharedService} from './shared.service';

@Component({
  selector : "other",
  template : `
    I'm the other component. The shared data is: 
    <p>{{data}}</p>
  `,
})
export class OtherComponent implements OnInit{
  data: string;
  constructor(private _sharedService: SharedService){}
  ngOnInit() {
    this.data = this._sharedService.dataString;
  }
}

Here's a plunkr.

When text is added to the input and the button is clicked I want to display the value entered in the 'other' component, just to demonstrate getting and setting the service data. However, it's just silently failing.

Can anyone explain what I'm doing wrong?

Thanks


Solution

  • Your code is correct, it's just your other component do not know that you updated the service, so it will not request a new Data. For this case Angular2 is using Observables :

    The Service :

    @Injectable()
    export class SharedService {
      // Observable string source
      private dataStringSource = new Subject<string>();
    
      // Observable string stream
      dataString$ = this.dataStringSource.asObservable();
    
      // Service message commands
      insertData(data: string) {
        this.dataStringSource.next(data)
      }
    }
    

    The Main Component

    @Component({
      selector: 'my-app',
      providers: [SharedService],
      directives: [OtherComponent],
      template: `
        <input type="text" #someValue>
        <button (click)="setSharedValue(someValue.value)">Change value in shared service</button>
        <br><br>
        <other></other>
      `
    })
    export class AppComponent { 
      constructor(private _sharedService: SharedService){}
    
      setSharedValue(value){ 
        this._sharedService.insertData(value);
      }
    }
    

    The Other Component

    @Component({
      selector : "other",
      template : `
        I'm the other component. The shared data is: 
        <p>{{data}}</p>
      `,
    })
    export class OtherComponent implements OnInit{
      data: string;
      constructor(private _sharedService: SharedService){}
    
      ngOnInit() {
        this._sharedService.dataString$.subscribe(
          data => {
            this.data = data; 
          });
      }
    }
    

    The updated plunker can be found here : https://plnkr.co/edit/neM6EdYYUkGkRpF0fKGS?p=preview

    Interaction between components in Angular2 can be found here : https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service