drbishop drbishop - 2 months ago 12
Javascript Question

How to reuse service calls in Angular 2

I have two components using the same service. On

FirstComponent
, I get some data from a service:

getLiveData() {
Observable.interval(1000)
.mergeMap(() => this.service.getData())
.subscribe(
res => this.data = res,
err => this.error = err
);
}


At first, I've added another
getLiveData()
to the
SecondComponent
. However, that way I'm making two REST calls every second. That shouldn't be needed as I want to use the same service.

So, can I reuse that in the
SecondComponent
without making two calls every time?

I tried to add the
FirstComponent
as a service and called
this.service.data
but I'm getting
undefined
.

PS. I also need the values to be updated every second on both components.

UPDATE: I've posted a Plunker following Madhu's advice. I managed to get only one call per time, but I'm not getting any data from it.

Answer

You may try below,

@Injectable()
export class MyAwesomeService{
  _streamingData: Subject<any> = new Subject<any>();
  streamingObservable = {};

  get streamingData$(){
    return this._streamingData.asObservable();
  }      

  getLiveData(){
    if(!!this.streamingObservable){
    const start = 10;
    this.streamingObservable =  Observable
         .interval(1000)
         .mergeMap(() => this.service.getData())
         .subscribe(
            res => {
              this._streamingData.next(res);
            },
            err => {
              console.log(err);
            }
         );
    }
    return this.streamingObservable;
  }
}

@Component({
  selector: 'my-app',
  template: `<h3>Live streaming data</h3>
   <hr />
   <child-comp-1></child-comp-1>
   <hr />
   <child-comp-2></child-comp-2>
  `
})
export class AppComponent { }

@Component({
  selector: 'child-comp-1',
  template: `<h3>Child component</h3>
   Streaming Data: {{ data | async }}
  `
})
export class ChildComponent1 {
  data = "Hello!!";
  constructor(private myservice:MyAwesomeService){
    this.data= myservice.streamingData$;
    myservice.getLiveData();
  }
}

@Component({
  selector: 'child-comp-2',
  template: `<h3>Child component 2</h3>
   Streaming Data: {{ data | async }}
  `
})
export class ChildComponent2 {
  data = "Hello!!";
  constructor(private myservice:MyAwesomeService){
    this.data= myservice.streamingData$;
  }
}

Here is the Plunker!!, In Plunk i have simulated service data with a simple map which gives data at an interval.

Hope this helps!!