What steps can I take to avoid conflicts between behavior subjects when making next() calls?

I am facing an issue with a BehaviorSubject variable named saveToLocalStorage. In one of my methods, the next() method is called twice, but only one of the calls is being completed while the other one gets overwritten. The service subscribed to these calls is responsible for saving data to local storage and nothing else. To address this issue, I decided to handle the calls within an Observable with a delay between the calls. Here is an example:

Observable.of(1).pipe(
  tap(()=> {if(this.currentWebAppMode !== newMode){
    this.saveToLocalStorage.next([DataType.STORED_RESULTS, null])}; 
  }),
  debounceTime(100))
  .subscribe(result => this.saveToLocalStorage.next([DataType.WEB_APP_MODE, newMode]));  

While this solution works, it feels like a hack. I am looking for a more proper way to ensure that both subsequent next() calls to saveToLocalStorage can execute properly.

Update: With Deborah's help, I was able to improve my solution by using the concatMap operator instead of tap and debounceTime. Here is the updated code:

Observable.of(1).pipe(
  concatMap(()=> {if(this.dataStoreService.currentAppMode !== newMode){
    this.saveToLocalStorage.next([DataType.STORED_RESULTS, null])};
  return of(true)}))
  .subscribe(result => this.saveToLocalStorage.next([DataType.WEB_APP_MODE, newMode]));

Answer №1

When you use the concatMap method, you ensure that each value from the source is processed in a sequential manner.

The following code snippet creates an "action" stream that emits values (in this case, 1 and 2).

As each value is emitted, the code runs the specified pipeline.

Within the pipeline, concatMap is utilized to guarantee full processing of each emitted value. If a new value is emitted before the processing of the previous value is complete, it is stored internally and processed after the current value.

In the provided example, the code invokes the doSave function to save data to local storage, returning true if the save is successful.

Here's a basic implementation:

  saveSubject = new BehaviorSubject<number>(1);
  saveAction$ = this.saveSubject.asObservable();

  source = this.saveAction$.pipe(
    concatMap(value =>
      this.doSave(value)
    )
  );

  ngOnInit() {
    this.source.subscribe();
    this.saveSubject.next(2);
  }

  doSave(value) {
    console.log('Emited value:', value);
    // Save to local storage
    return of(true);
  }

To see a live example, check out this StackBlitz: https://stackblitz.com/edit/angular-concatmap-deborahk

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble with react-responsive-carousel in Next.js version 13?

I have been following a tutorial to create an eBay clone. One of the steps involves creating a carousel. However, when I add it, the carousel does not transition to the next page. I have attempted to uninstall and reinstall packages, but the issue persists ...

Challenges when transitioning from Angular 8 to Angular 9

After transitioning from Angular 8 to Angular 9, I encountered the following issues. Despite removing and reinstalling node_modules multiple times, the problems persist: An unhandled exception occurred: Cannot find module 'webpack/lib/ParserHelpers&ap ...

Utilizing TypeDoc to Directly Reference External Library Documentation

I am working on a TypeScript project and using TypeDoc to create documentation. There is an external library in my project that already has its documentation. I want to automatically link the reader to the documentation of this external library without man ...

Even after rigorous type checking, TypeScript continues to throw the ts2571 error when handling an unidentified variable

Consider this scenario: the code snippet below will result in an Object is of type 'unknown'. error: let obj: {[key: string]: unknown} = {hello: ["world", "!"]}; // Could be anything with the same structure let key = "he ...

The utilization of the rest parameter in combination with generics

I encountered an issue with my iteration. The error message "Operator '+=' cannot be applied to types 'number' and 'T'" is showing up. I am puzzled as to why this is happening. let a: number = 1, b: number = 2, c: number ...

Struggling with parsing JSON in TypeScript/React because of type issues

Upon receiving an API response, I would like to parse the data since it is in the form of an array of objects. Here's an example of how the JSON looks: { "totalSize": "56", "sortedKeys": [ { & ...

React's setState is not reflecting the changes made to the reduced array

I am currently working on a custom component that consists of two select lists with buttons to move options from the available list to the selected list. The issue I am facing is that even though the elements are successfully added to the target list, they ...

The NbDatePicker does not display certain Spanish names

One issue I'm facing is with the Nb-DatePicker component in my project. I tried using {provide: LOCALE_ID, useValue: "es-MX"} in my app.component to display it in Spanish. However, when February, April, May, August, or December are selected, ...

Discover the process of transitioning your animations from Angular to CSS

I have successfully implemented a fade-in/out animation using @angular/animation, but now I am looking to transfer this animation to CSS and eliminate the dependency on @angular/animation. Here is my current animation setup (triggering it with [@fadeInOut ...

Concealing the value of the variable within the state function

CODE USED: /*Code snippet from another page with specific URL*/ .state("main/handler/location/userSso",{ url:"/main/handler/:location/:", templateUrl:"component/common/main.html", controller: 'MainContro ...

Can you provide input to the reducer function?

In the creator, an action is defined like this: export const actionCreators = { submitlink: (url: string) => <SubmitLinkAction>{ type: 'SUBMIT_LINK' } } In the component that calls it: public render() { return <div> ...

Using Rxjs to dynamically map values from an array with forkJoin

Greetings! I have a collection of Boolean observables and would like to apply a logical AND operation. Currently, I am passing static values 'a' and 'b', but I am unsure of the number of elements in the totalKeys array. import { forkJoi ...

Exploring the Benefits of Utilizing the tslint.json Configuration File in an Angular 6 Project

https://i.stack.imgur.com/j5TCX.png Can you explain the importance of having two tslint.json files, one inside the src folder and one inside the project folder? What sets them apart from each other? ...

Angular 8 throws a TS2339 error, yet the code is functioning perfectly and delivering the desired output

Upon compiling my code, I encountered the following error: ERROR in src/app/home/home.component.ts:13:37 - error TS2339: Property 'name' does not exist on type 'string | Type'. Property 'name' does not exist on type &ap ...

Angular2 application experiences exception in the karma test for checking karma

Is there a way for me to access more detailed logs? I'm struggling to pinpoint where the error is originating from. A critical error occurred while running my code: Chrome 57.0.2987 (Linux 0.0.0) ERROR Uncaught Response with status: 0 for URL: null ...

Struggling to create a route in Angular when selecting a dropdown item?

In my routing setup, I have a route called /gallery with 2 child routes: path: "gallery", component: GalleryComponent, children: [ { path: "photoAlbums", component: AlbumsComponent, children: [{ ...

"Encountering issues with iterating over a Mongo cursor after upgrading to Angular2 rc5

I'm currently working on a meteor/angular2 application and recently upgraded to rc5. Unfortunately, I encountered an error while trying to display a list of messages based on a mongo cursor in my component. I've tried to simplify the code for bet ...

Error in Typescript: The 'type' property is not found in the 'string' type

I am working on creating a React component that includes subcomponents within it. I came across this insightful article that has been guiding me through the process. The concept is to design a Modal component with distinct sections such as Modal.Header, M ...

Angular definitely typed does not convert into JavaScript

After installing TypeScript on my VS2013, I obtained the Angular 1.5 Definitely Typed from the NuGet package manager. Although angular.d.ts and its components do not generate angular.js file, when I create another TypeScript file like file1.ts, the file1. ...

Tips for fixing the HTTP error 431 in Next.js with Next-Auth

I am encountering an issue with rendering a photo in jwt via token. Tools utilized: nextjs, typescript, next-auth, keycloak, LDAP The image is retrieved from LDAP and passed to the keycloak user. My application is responsible for storing the jwt token po ...