Reputation: 465
I have widgets component which i want to loop , so that i can display data in that component dnamically.
Widgets Component:
export class WidgetsComponent implements OnInit, OnDestroy {
@Input() vId: any;
charts = {}
subscription: Subscription;
constructor(private widgetsService: WidgetsService){}
ngOnInit() {
console.log(this.vId)
this.charts[this.vId] = {};
this.widgetsService.getWidgets(this.vId);
this.subscription = this.widgetsService.widgetOption.subscribe(option => {
console.log('component', option); // problem is here (calls multiple times)
this.charts[this.vId] = option;
// console.log(this.charts)
})
}
ngOnDestroy() {
if(this.subscription) {
this.subscription.unsubscribe();
}
}
}
Widgets Service:
export class WidgetsService {
public widgetOption = new Subject<any>();
constructor(private http:HttpClient){}
getWidgets (id) {
this.http.get(`https://jsonplaceholder.typicode.com/users/${id}`).subscribe(
res => {
// console.log('res', res);
this.widgetOption.next(res);
}
)
}
}
Problem is same data is reflected in UI , because of multiple subscription calls.
If i loop widgets-component two times then subscribe calls 4 times and so on.
How can i avoid such multiple subscribe calls?
Note: If i dont loop widgets component then its works fine.
Here is the working demo for the same stackblitz_demo
Any help would be appreciated.
Thanks!!
Upvotes: 0
Views: 388
Reputation: 17762
You do not need any Subject
if you want to notify the result of an http call made via the Angular http client.
If you simplify your getWidgets
method like this
getWidgets (id) {
return this.http.get(`https://jsonplaceholder.typicode.com/users/${id}`)
}
you have a method that returns an Observable.
Now you can use this method directly within the ngOnInit()
method of WidgetComponents
like this
ngOnInit() {
console.log(this.vId)
this.charts[this.vId] = {};
this.widgetsService.getWidgets(this.vId);
this.subscription = this.widgetsService.getWidgets(this.vId).subscribe(option => {
console.log('component', option); //calls twice
this.charts[this.vId] = option;
// console.log(this.charts)
})
}
So you basically subscribe to the Observable returned by http client and you do not need any Subject to propagate the notification of the result (or error for that matter).
This is your corrected stackblitz.
Upvotes: 1