Angular API getting called multiple times due to subscription issue

1k Views Asked by At

I have two components dashboard.ts and myapplication.ts. These do not have any sort of relationship.

The dashboard has a pop-up, on selection of a value in this pop-up there has to be a change in the myapplication component (calling API's). For this i've created a service and added subject (also tried behaviour subject).

The issue is I'm subscribing to the subject inside myapplication component's ngOnInit() and now the user can again change the value using that pop-up functionality. So it's explicit that the myapplication.ts component has not got destroyed so when the user does this activity the subscription is increasing (means the api is called twice, thrice,.. based on how many times this activity happens). The API call's are getting called twice, thrice,.. and also getting cancelled for some calls.

I tried to unsubscribe at the end of ngOnInit() hook, it does unsubscribe but the user when make change in the pop-up nothing happens in this myapplication.ts component.

Dashboard.ts

// this method is called when the pop-up is closed (it has the selected data's id/index)
  toCheckForAvailability(id:any) {
  if(isAvailable) {
    this.add(id);
  } else {
    this.sharedService.changeEId(-1);
    this.sharedService.changeName("hello test");
  }
  }

add(id:any) {
    this.sharedService.changeEId(id);
    this.sharedService.changeName("hello test");
//calling an api to add the data if on free trial routing to subscription and also updating the subscription observable
}

myapplication.ts

ngOnInit() {

  this.subjectSubscription = this.sharedService.eIDChosen.subscribe(x => {
    console.log("inside sub for essay id")
    this.subjectSubscription = this.sharedService.cName.subscribe(x => this.Name = x);
    if(x === -1) {
      id= Details[index].id;

let sub_status = true;
this.subjectSubscription = this.sharedService.subscription.subscribe(x=> sub_status = x)

        if( sub_status === 'true') {
          console.log('inside befor api call')
          this.subscription = this.http.postData('add', {eid:id}).pipe(take(1)).subscribe((res:any) => {
            console.log('inside api calld')
            if (res.success) {
              this.toastr.success(res && res.message);
              this.dashboard();
              if(this.subscription) {
                this.subscription.unsubscribe();
              }
            
            }
          }, ({error}) => { 
            this.toastr.error(error && error.message);
            if(error.data.reason === 'invalidPlan') {
              this.router.navigate(['/subscription']);
              this.sharedService.changeSubscriptionStatus(false);
              if(this.subscription) {
                this.subscription.unsubscribe();
              }
            }
          });
        }
      }
      })
}

sharedservice.ts

  export class SharedService {

    public Json$ = new Subject<JSON>();

    public editDataDetails: any = '' ;
    public cID: any = 0;
    public eID: any = 0;
    public isValidSubscription = true;
    public subject = new Subject<any>();

    public cName = new  Subject<any>();
    public cIdChosen = new Subject<any>();
    public eIDChosen = new Subject<any>();
    public subscription = new Subject<any>();

    //behaviour subject
    // private cName = new  BehaviorSubject(this.editDataDetails);
    // private cIdChosen = new BehaviorSubject(this.cID);
    // private eIDChosen = new BehaviorSubject(this.eID);
    // private subscription = new BehaviorSubject(this.isValidSubscription);
    currentMessage = this.cName.asObservable();
    currentCSelected = this.cIdChosen.asObservable();
    currEss = this.eIDChosen.asObservable();
    currentSubscriptionStatus = this.subscription.asObservable();

    changeId(val: Number) {
      this.cIdChosen.next(val);
    }
    changeName(message: string) {
    this.cName.next(message);
    }
    changeEId(id: Number) {
      this.eIDChosen.next(id);
    }

    changeSubscriptionStatus(status: boolean) {
      this.subscription.next(status)
    }

    changeCDetails(c_info:any) {
      this.Json$.next(c_info);
    }
  }

1

There are 1 best solutions below

1
Nirav Ghodadra On

Use RXJS operator and your problem would be solved.

For example just add this before subscribing

 .pipe(first())
  .subscribe

so it'll only give you the first emitted value or if you are getting fixed number of value then you can use skip to skip operator the desired values