What is the best way to trigger an Action/Effect after all properties in my state have been initialized?

I am facing a challenge in my Angular application where I need to initialize three properties on the state of the reducer before calling a dispatch that triggers an effect to load data from the server. However, when I debug the effect, the data returned is null indicating that the values haven't been set yet.

I understand that I should subscribe to the state changes and react accordingly, but I'm struggling to figure out how to properly sequence the assignment of these three state properties followed by the dispatch to load data from the server using NgRx. Below is a snippet of the code I'm working with:

Inside ngOnInit

this.store.dispatch(actions.set_foo({ value: "A" }))
this.store.dispatch(actions.set_bar({ value: "B" }))
this.store.dispatch(actions.set_baz({ value: "C" }))

// This dispatch triggers an effect that requires data from state.foo, state.bar, and state.baz
// How can I ensure that the assignment of Foo, Bar, and Baz has completed before this call?
this.store.dispatch(actions.load_data_from_server());

Inside the effect being triggered

loadData$ = createEffect(
  ()=>this.actions$.pipe(
    ofType(actions.load_data_from_server),

    // selectParameterData returns a composite object of Foo/Bar/Baz.
    // Is there a better way to achieve this than what I'm doing currently?
    withLatestFrom(this.store$.select(selectors.selectParameterData),
    mergeMap([action, data]=>
    
    ... Code to fetch data from the server using values from Foo/Bar/Baz ...
        The issue lies here as the data is uninitialized.   
  )
)

I'm open to restructuring the code to address this problem as part of our application's migration to NgRx. Any assistance on how to properly handle initializing multiple state properties before fetching data from the server would be greatly appreciated.

Therefore, how can I ensure that multiple properties are set on the state and only then proceed to load data from the server, ensuring that the loaded data references those properties on the reducer state object?

Answer №1

To link the action handlers together, you can do it in the following way:

Starting from ngOnInit

this.store.dispatch(actions.set_all({ a: "A", b: "B", c: "C"} ));

Within the called effect

setAll$ = createEffect(
  () =>  this.actions$.pipe(
      ofType(actions.set_all),
      concatMap(t => {
         return [
            actions.set_foo({ value: t.a} ),
            actions.set_bar({ value: t.b} ),
            actions.set_baz({ value: t.c} ),
            actions.load_data_from_server
         ];
      })
)
loadData$ = createEffect(
  ()=>this.actions$.pipe(
    ofType(actions.load_data_from_server),

    //selectParameterData is a selector that returns a composite object of Foo/Bar/Baz. There might be a better way to do this, but this allowed me to get three state properties in one.
    withLatestFrom(this.store$.select(selectors.selectParameterData),
    mergeMap([action, data]=>
    
    ... Code that makes a request to the server, using values from Foo/Bar/Baz ...
        Data is now initialized.   
  )
)

Another Approach

Alternatively, you can use the async scheduler along with setTimeout to schedule the dispatch, triggering the last action in the next event loop cycle. Note: This may cause change detection to run twice compared to the previous method.

this.store.dispatch(actions.set_foo({ value: "A"} ))
this.store.dispatch(actions.set_bar({ value: "B"}))
this.store.dispatch(actions.set_baz( { value: "C" }))
setTimeout(() => {
    this.store.dispatch(actions.load_data_from_server());
});

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

Troubleshooting: Unable to Sort Column in ngx-DataTable Angular 4

As a newcomer to Angular, I have been encountering some challenges while using ngx-DataTable. I am currently utilizing a simple ngx-DataTable for basic operations. The issue I am facing is that the sorting functionality is not working on a specific column, ...

What steps should I follow to create a versatile table component?

Can you please advise me on how to create generic data in a table using Typescript? I encountered this error message while trying to useTable({ at line data The error states: Type 'T[]' is not assignable to type 'readonly object[]'. ...

Exporting items with a label in TypeScript/JavaScript

Is it possible to rename the functions that are exported using the following syntax in Typescript/Javascript? export const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors(selectState); I would like to import selectAll as sele ...

Leverage the power of Angular by configuring a custom webpack setup to

Implementing the CSS modules concept in my Angular app has been a challenge due to conflicts with existing frontend CSS. My project utilizes SCSS, and I am looking for a way for webpack to modularize the CSS generated from SCSS during the final build step. ...

Access NgModel from NgForm

Is there a way to access the NgModel of a FormControl retrieved from the NgForm.controls object within its parent form, or directly from the form itself? Upon form submission, I pass the form as a parameter to a custom function: <form #myForm="ngForm" ...

What is the reason behind the existence of the "/path1/(<outlet-name>:'path2')" in Angular 4 Router?

Is the use of URLs like "/services/55/(section:'data')" a method to link named outlets and paths together? I am confused as to why it couldn't just be simplified to "/services/55/data" when there is already a Route set up with the outlet pro ...

When the pathway is void, it becomes impossible to redirect to the designated component

I recently developed a code that is supposed to redirect to a specific component when the application starts. const routes: Routes = [ {path: 'home', component: HomeComponent}, {path: 'content', loadChildren: 'app/componen ...

The error message thrown when running `ng test` states that the module '@angular-cli/plugins/karma' cannot be found

I have been exploring testing in my project and came across a suggestion to update the karma.conf.js file. The recommendation was to change angular-cli/plugins/karma to @angular-cli/plugins/karma, which involved adding the @ symbol before 'angular-cli ...

The camera in Three.js always returns as undefined when configuring ray tracing

Working on a project in Angular (8) with three.js, I am trying to calculate the distance between two points on the screen. Despite having set up mouse events and visible points, I am running into issues with ray tracing. Every time I try to use setFromCame ...

`Why does the npm test command in vue2 source code fail with the error "Type ... is not assignable to type ..."?`

After cloning the Vue source code from github using git clone, I proceeded to install dependencies by running yarn. However, when I ran npm test, the test failed. https://i.sstatic.net/aZXBg.png Does anyone have insight on why this error occurred and how ...

Mistakes encountered following the installation of lodash in Angular 2

After adding lodash to my Angular 2 project, I encountered a significant number of errors. To troubleshoot, I created a new project using the CLI: ng new tester, then I added lodash with npm install --save @types/lodash. When I ran ng serve, I received the ...

Embarking on a New Project with Cutting-Edge Technologies: Angular, Node.js/Express, Webpack, and Types

Recently, I've been following tutorials by Maximilian on Udemy for guidance. However, I have encountered a roadblock while trying to set up a new project from scratch involving a Node/Express and Angular 4 application. The issue seems to stem from the ...

Getting Typescript Compiler to Recognize Global Types: Tips and Strategies

In the top level of my project, I have defined some global interfaces as shown below: globaltypes.ts declare global { my_interface { name:string } } However, when attempting to compile with ts-node, the compiler fails and displays the er ...

Converting Typescript Object Types to Array Types with Tuple Structures

Presently, I have the following: interface Obj { foo: string, bar: number, baz: boolean } The desired outcome is to convert this interface into the tuple format below: [string, number, boolean] Is there a way to achieve this conversion? Up ...

Issue encountered when attempting to launch Angular website post installation of @ngx-translate package

My application is using @ngx-translate/core Version 14.0.0 and @ngx-translate/http-loader Version ^7.0.0 for multiple language support in Angular. I referred to tutorials like this one and my Angular version is 11.2.10. Despite successfully following all ...

Debugging with Android deep links

Currently, I am facing a challenge with my Ionic Angular application. It involves directing users to a browser for authentication via Auth0 and then redirecting them back to the application. However, the redirection is not happening due to the lack of deep ...

Enhancing TypeScript builtin objects in Netbeans using a custom plugin

While in the process of converting JavaScript code to TypeScript, I encountered a challenge with extending built-in objects using Object.defineProperty, such as String.prototype. Object.defineProperty(String.prototype, 'testFunc', { value: funct ...

Incorporating Parse into Angular 2 using TypeScript

While I am aware that angular2 is still in beta, I decided to give it a try. I followed the angular2 quickstart guide available at https://angular.io/docs/js/latest/quickstart.html and everything seemed to be working fine. Now, I wanted to integrate Parse ...

Specifying data types for keys within a generic parameter that is inferred

Objective I am currently developing a utility with the following interface: interface F<M extends Record<string, Function>> { ( listeners: M, options: { filter: e => boolean } ): void } An important aspect here is the filter o ...

Making the right choice: Class vs Interface in your Angular project

Today, I find myself pondering a question regarding classes and interfaces in Angular. In my opinion, here is my take on the matter: Interfaces are utilized in Typescript for type-checking purposes, existing until transpilation and disappearing in produc ...