Implementing NGRX sequential actions triggered from a component

I am attempting to send sequential requests to the ngrx-store in order to save two different entities in randomly chosen MongoDB collections. The challenge lies in needing a response from the first ngrx-store effect in order to utilize the data in another one when creating an entity that references the first one.

Here is what I have:

Reducer

...

Action

...

Effect

...

Selector

...

And service

...

All of this setup functions properly when I create only one entity from the component.

...

Other logic for creating different entities follows similar patterns as described above. However, calling an action within an action within the component can break the application state if not handled correctly. For instance, when trying to make additional actions after such nested calls, like editing or deleting contacts, the application state becomes unstable and errors occur.

On the other hand, dividing the logic into two independent calls results in issues because the application might not know the createdUser _id or userState.user._id at the time the createContact method is called, leading to errors.

I believe there needs to be a more intricate implementation of logic to handle these scenarios correctly. If you have any suggestions on the proper way to accomplish this, please advise me accordingly.

Thank you in advance.

Answer №1

You are facing challenges related to managing your subscription.

Here are some suggestions for working with NGRX in a more efficient manner:

Firstly, let's focus on your "dispatcher" service/model, or whatever term is used currently for the service responsible for dispatching actions.

createUser(user: IUser) {
    this.store.dispatch(new fromStore.UserCreate(user));
    return this.store.select(fromStore.getUserState);
  }

While having a separate method to call the store is good practice, returning the store selector directly may not be ideal due to two reasons:

  • There is a high possibility of needing data already stored inside the store without reloading it.
  • Sometimes you may want to dispatch an action without subscribing to a specific field from the store.

Refactored version:

user$ = this.store.select(fromStore.getUserState);
createUser(user: IUser): void {
    this.store.dispatch(new fromStore.UserCreate(user)); 
  }

Next, let's examine the component where you initiate the create user request:

user-create.component.ts

onCreateUser() {
    this.us
      .createUser({
        // User details here
      })
      .subscribe((user) => {
        if (user) {
          // Actions after creating user
        }
      });
  }

Observing this code block reveals that each new user creation triggers a new subscription, potentially leading to multiple subscriptions and memory leaks.

Refactored approach introduces observables for user creation success handling, ensuring no memory leaks and duplicates:

Updated implementation shown in the refactored blocks.

In conclusion, nested subscriptions should be avoided for better code maintenance and efficiency. Refactoring your code as demonstrated will help enhance performance and prevent potential issues.

Remember to continue learning and exploring rxjs for improved development practices.

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

Designing a unique and customized theme for Angular 4

Exploring the world of Angular 4 and Angular Material is an exciting journey for me. Currently, I am delving into the creation of a custom theme in Angular 4. In order to achieve this, we make use of variables to assign colors to primary, accent, and warn ...

Differentiating Layout Routing in Angular 2

In my unique Angular 2 application, I am facing a challenge with the layout. The home page has a completely different layout compared to the rest of the app, which only share a navigation bar. Here are some sample URLs: http://localhost:4200/ <= ...

Using Angular: Passing a service as a parameter

I have a desire to improve the organization of my code by moving certain functions into an external file and accessing them from multiple components. These functions rely on a service: The MyFunctions Class import { Service1 } from "../_services&quo ...

Error: The parameter should be a string, not an object

I am having trouble with a function that is supposed to return a string but instead, it returns an object. Unfortunately, I cannot use the .toString() method either. currentEnvironment: string = "beta"; serverURL: string = this.setServerURL(this.currentEnv ...

What is the contrast between element.getAttribute() value and a String in protractor?

When using protractor and typescript, I need to verify that the text saved in a textbox matches a certain string by comparing it with the resulting value of element.getAttribute("value"). Unfortunately, getText() does not work for this scenario b ...

What steps are involved in launching an outdated Angular project?

Tasked with reviving an old Angular client in my company, I found myself grappling with outdated files and missing configurations. The lack of package.json, package-lock.json, and angular.json added to the confusion, while the presence of node modules in t ...

Tally up identical words without considering differences in capitalization or extra spaces

Let's take an example with different variations of the word "themselves" like "themselves", "Themselves", or " THEMSelveS " (notice the leading and trailing spaces), all should be considered as one count for themselves: 3 ...

The custom Ionic slides component {Slides} will only update the reference of the last created slide component

Desired outcome: When incorporating multiple ionic slides components into a page, the ability to reference and adjust their properties based on screen size is expected. Current situation: Upon adding multiple ionic slides components to a page and attempti ...

How do I condense nested keys in TypeScript?

If I have two types defined in TypeScript: interface Foo { bar: string; } interface Baz { foo: Foo; } Is it possible to flatten the Baz type in TypeScript (e.g. type FlatBaz = Flatten<Baz>), so that the signature appears similar to this? inte ...

Angular does not completely erase everything

Having some issues with file deletion while working on angular and typescript. My setup involves three interfaces: Project, SubProject, and Position. When a subproject is added to the selected project, it gets included in the subProjectIds list of the Proj ...

How to Install Definitely Typed Packages in Visual Studio 2015 RC for AspNet5 with the Help of Gulp and TSD

Struggling to add angular.d.ts to my MVC6 project, I've hit a roadblock. Although I've configured Gulp to reinstall necessary packages using tsd, I'm stuck on the initial installation process. The instructions suggest running 'tsd inst ...

Angular pagination refers to the process of dividing a large

Currently utilizing ngx-pagination https://www.npmjs.com/package/ngx-pagination app.module: import { NgxPaginationModule } from 'ngx-pagination'; @NgModule({ declarations: [ AppComponent, ... ], imports: [ ... NgxPaginat ...

Using InjectionToken within an Angular APP_INITIALIZER function

I am currently working on implementing an APP_INITIALIZER in my Angular 10 project. The factory function I'm using has multiple dependencies, one of which is an InjectionToken<string>. However, I have encountered an issue when trying to inject i ...

Troubleshooting a NestJS application within an Nx workspace by configuring a VScode Launch setup

I am facing an issue in VSCode while trying to launch a NestJS application using Nx in debug mode. I have the VSCode nightly js debugger extension installed, but something seems to be going wrong. I attempted to add type "module" to the package.json file, ...

When using React MUI Autocomplete, make sure to handle the error that occurs when trying to filter options using the

I am trying to implement an autocomplete search bar that makes a custom call to the backend to search through a list of tickers. <Autocomplete multiple id="checkboxes-tags-demo" options={watchlis ...

Creating React Components with TypeScript: Ensuring Typechecking in Class and Function Components

Want to ensure typechecking works when defining React Class/Function components in TypeScript? Struggling to find a comprehensive guide on how to do it correctly. I've managed to define the Props and State interfaces, but I'm unsure about how to ...

Can someone provide guidance on effectively implementing this JavaScript (TypeScript) Tree Recursion function?

I'm currently grappling with coding a recursive function, specifically one that involves "Tree Recursion". I could really use some guidance to steer me in the right direction. To better explain my dilemma, let's consider a basic example showcasi ...

What is the injection token used for a specialized constructor of a generic component?

I created a versatile material autocomplete feature that I plan to utilize for various API data such as countries, people, and positions. All of these datasets have common attributes: id, name. To address this, I defined an interface: export interface Auto ...

The Lenis smooth scrolling feature (GSAP) is not functioning properly

I have encountered an issue with the smooth scrolling feature of gsap causing a delay on my website. This problem is only resolved when I manually go into the browser settings and disable smooth scrolling by navigating to chrome://flags/#smooth-scrolling ...

What is the best way to establish the primary color for the entire app?

Is there a way to easily set the color for @react-native-material/core's theme? I managed to change the color but I don't want to have to do it individually for each component. ...