Angular2/4 : Refresh Data Realtime
You should be able to do this without problems:
ngOnInit() { this.refreshData(); this.interval = setInterval(() => { this.refreshData(); }, 5000);}refreshData(){ this.myService.getData() .subscribe(data => { this.data = data; }) );}
As per this post Angular will take care of cleaning up after itself.
However, if you're going to have a live data stream in your app I'd suggest changing your component so that rather than subscribing to each response of your service's http request, you instead subscribe once to a new observable data$
property of your service in your component's ngOnInit()
. Then, on interval (as you're doing) call updateData()
on your service (or setup the interval inside your service) but don't subscribe. When your service successfully fetches the data, it pushes the next value to its observable data$
property, giving you a stream of data from your service that you can react to anywhere in your app.
ngOnInit() { this.myService.data$.subscribe(data => { // subscribe once to the data stream this.data = data; }) this.refreshData(); this.interval = setInterval(() => { this.refreshData(); }, 5000);}refreshData(){ this.myService.updateData(); // simply signal for the service to update its data stream}
With myService.data$
being an observable BehaviourSubject updated in your service, something like this:
public data$: BehaviorSubject<any> = new BehaviorSubject({});updateData() { let data = this.http.get('http://www.data.com').map((data)=>{ return data.json(); }).do((data)=>{ this.data$.next(data); })}
That way you can avoid multiple subscriptions and make the data stream available to any component that needs it.
I am just extending @SpaceFozzy's answer a little bit so that it will be helpful for future visitors here. For refreshing the data, I have used the way of @SpaceFozzy. But for subscriptions, I got a better approach. Please have a look at the answer - https://stackoverflow.com/a/41177163. So I have updated my service and component as follows. Hope this helps.
My Component
import { Subject } from 'rxjs/Subject';export class MyComponent implements OnInit, OnDestroy { private unsubscribe: Subject = new Subject(); data: any; interval: any; ngOnInit() { this.refreshData(); if(this.interval){ clearInterval(this.interval); } this.interval = setInterval(() => { this.refreshData(); }, 10000); this.myService.data$.takeUntil(this.unsubscribe) .subscribe(data => { this.data = data; }); } ngOnDestroy() { this.unsubscribe.next(); this.unsubscribe.complete(); } refreshData(){ this.myService.updateData() .takeUntil(this.unsubscribe) .subscribe(); } doAction(){ this.subscription.add( this.myService.doAction() .subscribe(result => { if(result === true){ this.refreshData(); } }) ); }}
My Service
import { Observable, BehaviorSubject } from 'rxjs';@Injectable()export class MyService { private dataSubject: BehaviorSubject<YourDataModel[]> = new BehaviorSubject([]); data$: Observable<YourDataModel[]> = this.dataSubject.asObservable(); updateData(): Observable<any> { return this.getData().do((data) => { this.dataSubject.next(data); }); } // My data is an array of model objects getData(): Observable<YourDataModel[]>{ return this.http.get('/path') .map((response: Response) => { let data = response.json() && response.json().your_data_objects; if(data){ return data; } }) }}
Please don't forget to clearInterval on ngDestroy.
ngOnDestroy() { this.unsubscribe.next(); this.unsubscribe.complete(); clearInterval(this.interval); }