Home > Software design >  Calling a service within an observable subscribe
Calling a service within an observable subscribe

Time:12-08

Service1.ts

public allFlags$: BehaviorSubject<FlagName> = new BehaviorSubject<FlagName>("feature-flag-1");

which is set like this:

    private _setFlags = () => {
    const allFlags = this._ldClient.allFlags();

    if (allFlags && Object.keys(allFlags).length > 0
        || (!isUndefinedOrNullOrEmpty(localStorage.getItem(LocalStorageKeys.LaunchDarklyFlags)
            && JSON.stringify(allFlags) !== localStorage.getItem(LocalStorageKeys.LaunchDarklyFlags)))
       ) {
      this._flags = allFlags;
      // Notify the subscribers just in case someone is watching this
      // before setup completes.
      this.allFlags$.next(this._flags);
      localStorage.setItem(LocalStorageKeys.LaunchDarklyFlags, JSON.stringify(this._flags));
    }
  }

And it is consumed on the component like this: Component1.ts

this._launchDarklyService.allFlags$.subscribe(flags => this._allFeatureFlags(flags))

private _allFeatureFlags = (flags: FlagName): void => {
    flags = JSON.parse(this._launchDarklyService.getAllFlags())

    if (!(flags && Object.keys(flags).length === 0)) {
        let err = new WebClientException();
        err.ErrorMessage = 'LaunchDarkly- AllFlags- '   JSON.stringify(flags);
        err.LogType = LogType.INFO;
        this._observable = this._userService.reportError(err)
                            .subscribe();
    }
}

The issue here is since I am subscribing(making a post call) inside an Observable subscribe, as a result there are multiple logs in the EventLogger. How can I fix this?

CodePudding user response:

It sounds like what you want to do is only fire 1 http call - this._userService.reportError(err) each time allFlags$ observable pushes next data. There are multiple ways to achieve this - I'd look into rxjs's take for how you can only listen for first data from observable. Something like this.userService.reportError(err).pipe(take(1)).subscribe()

Or you can turn that observable into a promise through toPromise() method, which only emit once and then complete

Alternatively, since calls to .subscribe() return you a way to unsubscribe, you can call that method after your first subscription resolves: const unsubscriber = myApiCall.subscribe(() => unsubscriber.unsubscribe());

  • Related