Using ngrx to pass the payload from one action to trigger the next action

As a beginner in ngrx and Angular development, I am exploring how to manage a collection of trades in my store. An effect is set up to listen for LoadTradeRequest, which triggers an HTTP request to fetch Observable data and then either dispatches a LoadTradeSuccess or LoadTradeFailure action based on the response.

@Effect()
loadTrade$: Observable<Action> = this.actions$.pipe(
ofType(ActionTypes.LoadTradeRequest),
mergeMap((action: actions.LoadTradeRequest) =>
  this.remoteApiService.loadTrade(action.payload).pipe(
    map(trade => new actions.LoadTradeSuccess(trade)),
    catchError(err => of(new actions.LoadTradeFailure(err)))
  )
 );

In order to handle the LoadTradeSuccess action, a reducer function is implemented to add the loaded Trade to the existing state in the store.

case ActionTypes.LoadTradeSuccess: {
  return { ...state, trades: [...state.trades, action.payload] };
}

The current State is declared as:

trades: Trade[];

Everything is functioning smoothly at this point. Now, the requirement is to modify the State so that the trades collection is organized with a unique identifier provided in the action payload of LoadTradeRequestAction.

Updated State Structure:

trades: DictionaryItem<string, Trade>[];

Here's the structure of DictionaryItem interface:

export interface DictionaryItem<K, V> { 0: K; 1: V; }

I am seeking guidance on how to pass a specific property from the triggering action to the subsequent action along with the HTTP response data. Below is a non-functional code snippet intended to illustrate the desired outcome:

@Effect()
loadTrade$: Observable<Action> = this.actions$.pipe(
ofType(ActionTypes.LoadTradeRequest),
mergeMap((action: actions.LoadTradeRequest) =>
this.remoteApiService.loadTrade(action.payload).pipe(
map(trade => new actions.LoadTradeSuccess({**action.payload.UniqueIdentifier**, trade})),
catchError(err => of(new actions.LoadTradeFailure(err)))
 )
)

Answer №1

Your action constructor should always require two parameters:

class SuccessTradeLoaded {
  constructor(readonly identifier: any, readonly  tradeData: any){}
}

Alternatively, you can use a payload object, but in that case, you need to create the object within the effect:

class LoadTradeSuccess {
  constructor(readonly payload: any){}
}


map(trade => new actions.LoadTradeSuccess({identifier: action.payload.UniqueID, tradeData: trade })),

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

I'm unable to provide an ID value within the modal section

<div class="table"> .... <tr *ngFor="let product of products; index as i"> <th scope="row">{{ i + 1 }}</th> <td>{{ product.name }}</td> <td>{{ product.category }}</td> <td> ...

Does the AngularJS ng-repeat Directive render all items in the browser whenever a single item is updated?

Imagine having a collection with 5000 records and only updating one record from it. Will the browser render all 5000 entries again? ng-repeat="item in ctrl.employeeData" After receiving updates for individual records, it takes between 2 to 5 seconds to r ...

Error in ReactJS: TypeError - Trying to convert undefined or null as an object

Here is the affected code with Typescript errors in local. The component name is correct: {template.elements.map((element: TemplateElementModel, i) => { const stand = roomStands?.find( (stand: ExhibitorModel) => stand.standN ...

Is it feasible to incorporate a method into a prototype and ensure that 'this' is associated with the appropriate type in TypeScript?

I have a scenario where I need to add a new method to a prototype, specifically to a class created using TypeScript. Here is an example: declare module "./MyClass" { interface MyClass { myNewMethod(); } } MyClass.prototype.myNewM ...

How can I access properties of generic types in TypeScript?

Converting the generic type to any is a valid approach (The type E could be a typescript type, class, or interface) of various entities like Product, Post, Todo, Customer, etc.: function test<E>(o:E):string { return (o as any)['property' ...

Is there a way to retrieve a compilation of custom directives that have been implemented on the Vue 3 component?

Is there a way to retrieve the list of custom directives applied to a component? When using the getCurrentInstance method, the directives property is null for the current component. I was expecting to see 'highlight' listed. How can I access the ...

Struggling with the Transition from Google Sign-In

Having difficulty transitioning from Google Sign-In. "{error: 'idpiframe_initialization_failed', details: 'You have created a new client application that use…i/web/guides/gis-migration) for more information.'}" How do I u ...

Do not allow nested objects to be returned

I am facing an issue with typeorm, where I have a queryBuilder set up like this: const projects = await this.conn.getRepository(UserProjectRelations).createQueryBuilder("userProject") .innerJoin("userProject.userId", ...

When the value of a Formcontrol is changed using valueAccessor.writeValue(), it remains unchanged

Encountering a similar issue as seen in this stack overflow post, but the solution provided isn't resolving the issue. Perhaps you can offer assistance on that thread. In my scenario, I have created a directive for formatting phone numbers: import { ...

While developing an exam portal with Angular and Spring Boot, I encountered an issue when trying to incorporate a name field as [name]

Component.html <div class="bootstrap-wrapper" *ngIf="!isSubmit"> <div class="container-fluid"> <div class="row"> <div class="col-md-2"> <!- ...

Turn off Inline CSS in Angular Universal

While rendering a site on the server with Angular Universal, the resulting page looks great. However, the source code of the pages contains an excessive amount of inline CSS (more than 50% of the document > 500kb), leading to slow download times especia ...

Including "entryComponents" in a TestBed

One of the challenges I'm facing involves a component that receives a class of another component to dynamically create as a child. let componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentToCreate); this.componentReferenc ...

Utilize a variable from one Angular component in another by sharing it between .ts files

My issue involves dynamically adding items to a todo list and wanting to exclude certain items. The challenge lies in the fact that the list itself is located outside of the task component: Within the task.component.html file, I iterate through the list f ...

Exploring the power of Vue.js reactivity using Object.defineProperty in a TypeScript environment

Currently, I am in the process of developing a TypeScript class to manage form submissions and handle server errors: export default class Form<Model> { private readonly original: Model private changes: Partial<Model> constructor(d ...

What are the steps to integrate Bootswatch into an Angular application?

I have a project using Angular and I'm looking to incorporate Bootswatch into it. However, I'm facing difficulties with the installation process. Initially, I attempted to install the module by running the command: npm i bootswatch After that, I ...

Issue with Vue @Watch not properly recognizing changes in a boolean value

I'm currently experimenting with watch functions in vue-ts. I have configured a watch function that is supposed to trigger whenever a Boolean variable's value changes, but for some reason, it's not triggering at all and I'm unable to de ...

What is the best way to manage a custom child event that is triggered using this.$emit in a parent component, specifically within the <script> section of the .vue file?

In our project, we're utilizing vue and typescript, which means that our .vue files are structured very similarly to the layout outlined in this blogpost. One of our child components is emitting a custom event called changeType. I'd like to trig ...

Exploring Click Events in Angular with OpenLayers Features

After creating a map with parking points as features, I now want to implement a click function for the features. When a feature is clicked, I want to display a popup with the corresponding parking data. I've tried searching online for information on ...

Generate a two-digit number within a looping structure

Hey there, I have a task where I need to generate numbers within a for loop. For numbers 1 to 9, I want to prepend '0' to them so they appear as 01, 02, 03...09, 10.... Here is how I approached it: for (var a = 1; a < 30; a++) { ...

The code breaks when the lodash version is updated to 4.17.4

After updating lodash to version 4.17.4, I encountered an error in Typescript that says: TypeError: _.uniqBy is not a function Uncaught TypeError: _.split is not a function The code snippet in question is as follows: import * as _ from 'lodash&apo ...