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:

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

The full execution of Jquery show() does not pause until it finishes

Here is the sequence I want to achieve: Show a div element with the CSS class yellow Execute a function for about 5 seconds Remove the yellow class and add the green CSS class "state Ok" However, when running my code, the div container does not appear u ...

What is the best way to generate conditional test scenarios with Protractor for testing?

Currently, there are certain test cases that I need to run only under specific conditions. it ('user can successfully log in', function() { if(siteAllowsLogin) { ..... } The problem with the above approach is that even when sitesNo ...

Nesting maps in JavaScript is a powerful way to transform

I'm in the process of developing a budgeting app using React and JavaScript. At the moment, I have successfully generated a table displaying various costs. Name Budget Used $ Used % Available Food 300 300 100 0 Streaming services 600 600 100 ...

Exploring MongoDB through proxyquire

To simulate a MongoDB dependency using proxyquire in my testing scenario, I have the following code snippet: var proxyquire = require('proxyquire'); var controller = path.resolve('.path/to/controller/file.js'); inside the before each ...

Click event not triggering to update image

I'm currently working on a Codepen project where I want to use JavaScript to change the image of an element with the id "chrome". However, my code doesn't seem to be working as expected. Can someone help me troubleshoot and fix this issue? Your a ...

Determine if the user has clicked on the Save or Cancel button within the print dialog box

Hello everyone, Can anyone help me figure out how to determine which button was selected by the user in a print dialog box? Thank you! ...

Passing the app variable from Express.js to routes

I am attempting to transfer some data from the app (variable defined as var app = express();) to some Socket.IO related code by sending a value to a middleware in a similar manner: function routes(app) { app.post('/evento', function (req, re ...

What is the best way to make a box modal function that displays a different image source than the one shown in the modal?

I'm looking to create a box modal that shows one image on the page, and then displays a different image in the popup when clicked. Here's what I currently have: <div class="row"> <div class="modal-image"><img id="myImg" src="http ...

Double invocation of useEffect causing issues in a TypeScript app built with Next.js

My useEffect function is set up with brackets as shown below: useEffect(() => { console.log('hello') getTransactions() }, []) Surprisingly, when I run my app, it logs "hello" twice in the console. Any thoughts on why this might be ...

Leverage the Express JS .all() function to identify the specific HTTP method that was utilized

My next task involves creating an endpoint at /api that will blindly proxy requests and responses to a legacy RESTful API system built in Ruby and hosted on a different domain. This is just a temporary step to transition smoothly, so it needs to work seam ...

Update: Cannot mark as invalid a nested document that has not been included in an array

I recently encountered an issue with my upsert query in mongoose. It was functioning perfectly in version 3.8, but ever since I upgraded to version 4, I've been facing the following error: Unable to invalidate a subdocument that has not been added to ...

Using Selenium to scroll down to an element until its 'style' changes

I'm in the process of scraping a review page similar to this one. While this specific page has only a few reviews, there are others with a larger volume that require extensive scrolling. Upon observation, I noticed that when the page is not complete ...

When running the `vue-cli-service test:unit` command, an error involving an "Unexpected token" message related to the usage of the spread operator

Within my code, I am utilizing the destructuring operator. However, during the module build phase, I encountered an "Unexpected token" error. Any suggestions on how to resolve this issue without completely rewriting my code to avoid using the destructuring ...

Does a DOM API exist specifically for querying comment nodes within the document?

My document contains a debugging comment that appears as follows: <!--SERVER_TRACE {...}--> Is there a method to search the DOM and access this specific node? I would prefer a vanilla JavaScript solution, without relying on any external libraries. ...

Tips for creating a tailored Express.js request interface using Typescript efficiently

I have been working on designing a custom Express request interface for my API. To achieve this, I created a custom interface named AuthRequest, which extends Request from Express. However, when attempting to import my interface and define req to utilize t ...

The React Material Component stubbornly resists being horizontally aligned in the Code Sandbox

Currently, I am working on getting my Material design to function properly within the CodeSandbox environment. One issue I am encountering is attempting to center it horizontally. As of now, it appears like this: To make it easier to identify its locati ...

Using jQuery or JavaScript to clear multiple selections in a multiselect dropdown when a button is clicked

Is there a way to clear the dropdown selections once my function saves data to local storage? You can refer to this fiddle for more details: http://jsfiddle.net/3u7Xj/139/ I already have code in place to handle other form elements: var $form = $("#formI ...

The Battle of node.js Modules: Comparing socket.io and express.static

The server.js file I am currently running is set up as follows: module.exports = server; var express = require('express'); var fs = require('fs'); var server = express.createServer(); var port = 58000; server.listen(port); var ...

Provide a TypeScript interface that dynamically adjusts according to the inputs of the function

Here is a TypeScript interface that I am working with: interface MyInterface { property1?: string; property2?: string; }; type InterfaceKey = keyof MyInterface; The following code snippet demonstrates how an object is created based on the MyInter ...

What steps do I need to take to incorporate Material UI icons into my REACT project?

After reviewing the documentation, I found it somewhat confusing with terms such as "MaterialIcon, SVGIcons, Icons". If you are interested, you can check out the link here. I am looking for a simple explanation of the process from installation to using th ...