Implementing NgRx state management to track and synchronize array updates

If you have multiple objects to add in ngrx state, how can you ensure they are all captured and kept in sync?

For example, what if one user is associated with more than one task? Currently, when all tasks are returned, the store is updated twice. However, each update replaces the last task with a new one. This behavior is expected, but how can you initialize an array to capture updates as an array of objects and keep them synchronized?

task.reducer.ts

import * as TaskActions from './task.actions';
import { Action, createReducer, on } from '@ngrx/store';
import { ITask } from '../../models/task';

export interface State {
  task: ITask | null;
  error: any;
}

const initialState: ITask = {
  basketTotal: 0,
  carePlanPrice: 0,
  category: null,
  completionDate: null
};

export const taskReducer = createReducer(
  initialState,
  on(TaskActions.getData, state => ({ ...state })),
  on(TaskActions.dataReceived, (state, payload) => ({ ...state, payload })),
  on(TaskActions.dataNotReceived, state => ({ ...state })),
  on(TaskActions.signOut, state => ({ ...state })),
  on(TaskActions.signOutSuccess, state => ({ ...state, ...initialState })),
);

export function reducer(state: ITask | undefined, action: Action) {
  return taskReducer(state, action);
}

task.effect.ts

  @Effect()
  getData$ = this.actions$.pipe(
    ofType(TaskActions.getData),
    switchMap(() => {
      return this.afs.collection<ITask>('tasks', ref =>
        ref.where('createdBy', '==', localStorage.getItem('uid'))).stateChanges().pipe(
      );
    }),
    mergeMap(actions => actions),
    map(action => {
      if (action.payload) {
        return TaskActions.dataReceived({ payload: TaskService.parseData(action.payload.doc.data()) });
      } else {
        return TaskActions.dataNotReceived();
      }
    })
  );

task.actions.ts

import { createAction, props } from '@ngrx/store';
import { ITask } from '../../models/task';

export const getData = createAction('[Task] Get Data');
export const dataReceived = createAction('[Task] Data Received', props<{ payload: Partial<ITask> }>());
export const dataNotReceived = createAction('[Task] Data Not Received');
export const signOut = createAction('[Task] Sign Out');
export const signOutSuccess = createAction('[Task] Sign Out Success');

Update:

I tried

on(TaskActions.dataReceived, (state, payload) => 
  ({ 
      ...state, 
      tasks: [...state.tasks,  payload.payload ] 
  })),

and this happened:

https://i.sstatic.net/w0iJX.png

I was expecting an array like this:

task: [
  { ... }, { ... }
]

Answer №1

An alternative method for replicating arrays involves the spread syntax.

on(UpdateActions.dataReceived, (state, payload) => 
  ({ 
      ...state, 
      updates: payload.status ? [...state.updates,  payload.newUpdate ] : []
  })),

To learn more about the spread syntax, check out the official documentation

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 encountering a "confirm" error within the data table. Any suggestions on how to resolve this issue?

When I try to use two datatables columns in confirm, an error occurs when the text 'do you want cancel?' is displayed. The issue seems to be with the text itself and not the code. How should we go about fixing this problem? This is my current cod ...

Unraveling a Map Object via an HTTP Request in Angular

I'm facing a puzzling issue. When I was using Angular 9.1, I had no problem sending a Map<string, string[]> through a request. However, after upgrading to Angular 13, this feature suddenly stopped working. Strangely, I couldn't find any inf ...

I'm looking to dynamically populate a DropDown list by utilizing Ajax in conjunction with a C# method. Can

Greetings, I have developed a C# method which looks like this: [WebMethod] protected static void populateDropdown(HiddenField hiddenControl, System.Web.UI.WebControls.DropDownList listinc) { int data = 0; string query; dat ...

Is it possible for me to save external CDN JavaScript files to my local system?

Normally, I would include scripts from other providers in my application like this: <script src="https://apis.google.com/js/api.js"></script> However, I am considering whether it is feasible to simply open the URL , and then copy and paste th ...

Mastering ReactJS: Error Encountered - Unexpected import Token

Just getting started with ReactJS and trying out some code from egghead.io. Unfortunately, I keep running into this error: Uncaught SyntaxError: Unexpected token import I've tried loading babel again and making sure to follow the lesson step by step ...

Retrieve an image using screen resolution parameters [using only HTML]

During a recent interview, the interviewer posed an interesting question regarding 2 images: There is one large resolution image that needs to be displayed on laptops and desktops. There is also a small image that should only be shown on mobile devices. ...

Using Telerik Grid in MVC to access the object that is passed to ClientEvent functions on the Javascript side

Here's a challenging question I have. I'm working with a Telerik Grid that has some ClientSide Events: .ClientEvents(events => events .OnDataBinding("SetAjaxParameter") ) Within the SetAjaxParameter function, I am setting parameters for ...

Can orbit controls be tweened in three.js?

When utilizing the TWEEN function within three.js, I have noticed that it is mainly used for tweening objects. Although I can successfully tween the camera's position, I am looking to also tween the orbit control to mimic following a target while the ...

What is the best way to set the length of an undefined item in an object to 0 in reactjs?

I am facing a challenge keeping track of scores within each article and displaying them accurately. The issue arises when there is a missing "up" or "down" item in the object. Below is the data containing all the votes: const votes = { "1": { "up": ...

Jest tests are failing to render React IonDateTime component

While executing Jest on an Ionic React component, I encountered a test failure consistently, regardless of whether the component had a time value or not. test('IonDateTime display', () => { render(<IonDatetime data-testid="foo" ...

Switching back and forth between classes prevents the animation from playing continuously, causing it to jump straight to the end

Currently, I am in the process of animating a hamburger menu with a unique twist. The idea is to have the top and bottom lines smoothly translate to the middle and then elegantly rotate into an X shape when clicked. My approach involves toggling between tw ...

Learn how to incorporate additional rows into a table by pressing the plus button within the table with the help of Angular

I require some assistance. I am looking to dynamically generate a row after clicking on the plus button using angular.js. The newly created row should contain an ID and model generated dynamically. Here is an overview of my code: <table class="table ta ...

Unfulfilled expectation of a promise within an array slipping through the cracks of a for loop

I have a function that generates a Promise. Afterward, I have another function that constructs an array of these promises for future utilization. It is important to note that I do not want to execute the promises within the array building function since so ...

The jQuery dynamic fields vanish mysteriously after being validated

I am facing an issue with my jQuery and validation. Below is the code snippet causing the problem: var fielddd = 1; $(document).on('click', '.btn.add-field', function() { fielddd++; $('#newfield').append('< ...

Is there a way to categorize items by their name in JavaScript?

Currently working with Node, I am in the process of developing an ID3 tag parser to extract the title, album, and artist information from MP3 files. My next step involves organizing the retrieved data by grouping them according to the album name. In my p ...

When deciding between .attribute=, setAttribute, and attr(), which is the best option to use?

.attribute in Javascript let friendDiv = document.getElementById("friend"); friendDiv.className = "list"; VS setAttribute in Javascript let friendDiv = document.getElementById("friend"); friendDiv.setAttribute("class","list"); VS .attr in Jquery $(" ...

Creating a text or JSON file in React using Node.js

I am completely new to React and have been practicing by creating a basic website. So far, I can render data from a JSON file and read data entered into a text box to display it in the log file. However, I am struggling with writing to a file. Can anyone ...

What is the best way to implement TrackballControls with a dynamic target?

Is there a way to implement the three.js script TrackballControls on a moving object while still allowing the camera to zoom and rotate? For example, I want to track a moving planet with the camera while giving the user the freedom to zoom in and rotate ar ...

Change the Angular Material 2 theme from light to dark with a simple click

I'm working on an Angular 2 Material project and I want to be able to switch the theme from dark to light with a single click of a button. Can anyone help me figure out how to achieve this? Any tips or advice would be greatly appreciated! ...

Include a new button in the react material-table toolbar

I am looking to enhance the material-table toolbar by adding a new button. This button will not be directly related to the table, but instead, it will open a modal window with additional information. The button I want to add is called "quotations" and I w ...