Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 771
Dan Avatar asked May 21 '16 12:05

Dan


1 Answers

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

like image 115
tibbus Avatar answered Oct 06 '22 04:10

tibbus