Suraj Gupta
Suraj Gupta

Reputation: 465

Subscribe calls multiple times when creating multiple instances of component

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

Answers (1)

Picci
Picci

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

Related Questions