Using *ngFor to dynamically update the DOM when an array is modified via ngrx

Currently, I am utilizing *ngFor to present values from an array:

[
  {
    id: 1,
    name: 'item1'
  },   
  {
    id: 2,
    name: 'item2'
  }
]

In the html:

<div *ngFor="let item of (items$ | async); trackBy: trackById;">
   // additional html for displaying data
</div

In the ts file:

items$: Observable<any>;
trackById = trackByProperty('id');

ngOnInit() {
  this.items$ = this.store.pipe(select(selectors.itemsSelector));
}

trackByProperty<T = any>(property: keyof T) {
  return (index: number, object: T) => object[property];
}

This method is functioning as expected, as ngFor captures the correct and current values in the items$ array

The problem arises when I update the items$ array through ngrx, it fails to detect the new array and does not refresh the DOM accordingly.

Here is the sequence of events using ngrx:

  1. A dispatch action is sent to the reducer, containing a new object to add to the array.

      this.store.dispatch(new actions.UpdateArray(
          { id: 3, name: 'item3' }
        )
      );
    
  2. The reducer processes this action by updating the store state with the modified array (including the new item).

    case actions.UPDATE_ARRAY: {
      const newItem = action.payload;
      const items = state.items;
      items.push(newItem);
      return {
        ...state,
        items
      };
    }
    
  3. The selector updates.

I have verified that the state is updated correctly by logging out the action.payload within the reducer.

Any insights on why the *ngFor does not reflect the updated array?

Note: I am using

changeDetection: ChangeDetectionStrategy.OnPush
as the change detection strategy in my component

Update

I discovered that the DOM does update when clicking on the component. Ideally, I would like it to update without requiring user interaction.

Answer №1

It is possible that this issue arises due to the Memoization feature utilized by NgRx selectors, which can lead to unexpected outcomes.

To resolve the issue, consider modifying the code snippet below:

case actions.UPDATE_ARRAY: {
  const newItem = action.payload;
  const items = state.items;
  items.push(newItem);
  return {
    ...state,
    items
  };
}

to the following implementation:

case actions.UPDATE_ARRAY: {
  const newItem = action.payload;
  const items = [...state.items, newItem]; // <-- creates new instance
  return {
    ...state,
    items
  };
}

This adjustment should effectively address the issue at hand.

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 ngbDatepicker within the Bootstrap angular framework is designed to seamlessly integrate with ngbPanelContent without causing overflow issues

I've integrated the ngbDatepicker into a form as shown below <ngb-panel> <ng-template ngbPanelTitle> <div class="row"> <ui-switch (change)="onChange($event,2)" [checked]="profession ...

Utilize Angular 5 to implement document uploads through a REST service call

I've been attempting to upload a document to our repository using Angular 5 and I'm encountering an error that I've included below. The Multipart/Form code is very similar to what worked in Angular 1.x, except for one line difference in the ...

What steps can be taken to troubleshoot and resolve this specific TypeScript compilation error, as well as similar errors that may

I am struggling with this TypeScript code that contains comments and seems a bit messy: function getPlacesToStopExchange(): { our: { i: number; val: number; }[]; enemy: { i: number; val: number; }[]; //[party in 'our' | 'enemy' ]: ...

What is the proper error type to use in the useRouteError() function in react-router-dom?

In my React project, I am utilizing the useRouteError() hook provided by react-router-dom to handle any errors that may arise during routing. However, I'm uncertain about the correct type for the error object returned by this hook. Currently, I have ...

I am looking for a way to convert the date format from "yyyy-MM-dd" to "dd-MM-yyyy" in NestJs

I need help with changing the date format from "yyyy-MM-dd" to "dd-MM-yyyy". Currently, my entity code looks like this: @IsOptional() @ApiProperty({ example: '1999-12-12', nullable: true }) @Column({ type: 'date', nullable: true } ...

Using React's higher order component (HOC) in TypeScript may trigger warnings when transitioning from non-TypeScript environments

I have a simple HOC component implemented in React with TypeScript. export const withFirebase = <P extends object>( Component: React.ComponentType<P> ) => class WithFirebase extends React.Component<P> { render() { return ...

Angular 2: Enhancing communication between directives and host components

I am facing an issue with a component that has 'header', 'content', and 'footer' divs in its template. Within the content div, I have implemented a custom directive to check for overflow in the div element. This part is workin ...

Managing the appearance of one DOM element using another DOM element

Hey there, I'm currently working on an Angular Material tooltip implementation. When I hover over my span element, the tooltip appears. Now, I'm wondering how I can dynamically change the background color of the tooltip based on certain condition ...

The email input should be the same red color as the other inputs, but unfortunately it is

When I enter the email address with first name and last name, it shows as invalid. However, the color on the CSS does not match. I am confused about why there is a difference between the two. I tried changing the type of email to text, but still no luck. ...

retrieving a date from a different source and displaying it in a date

Is there a way to ensure that the date format in an input of type date always follows the dd/MM/yyyy Brazilian pattern, regardless of the computer or browser specifications? <div class="input-group input-group text-center in ...

Is there a surefire method to ensure that ChromeDriver in Protractor consistently uses the stable version?

Every time Chrome releases an update, I encounter a recurring issue. Allow me to paint the picture: All browsers are at version 83 of Chrome Chrome announces that version 84 is on its way, but it has not been released yet. A new ChromeDriver 84 is rolled ...

Tips for utilizing multiple components in Angular 2

I am a beginner in angular2 and I am attempting to utilize two components on a single page, but I keep encountering a 404 error. Here are my two .ts files: app.ts import {Component, View, bootstrap} from 'angular2/angular2'; import {events} f ...

Whenever I navigate to a new page in my NEXTJS project, it loads an excessive number of modules

I am currently working on a small Next.js project and facing an issue where the initial load time is excessively long. Whenever I click on a link to navigate to a page like home/product/[slug], it takes around 12 seconds to load due to compiling over 2000 ...

Mastering the TypeScript syntax for executing the MongoDB find method

Having trouble properly typing the find method of MongoDB in my TypeScript project that involves MongoDB. Here's the snippet I'm working on: import { ReitsType } from '@/app/api/types/reits'; import { NextRequest, NextResponse } from &a ...

The mat-pagination component's mat-select feature is displaying unusual behavior

In a recent project I have created, users need to perform CRUD operations and view the output in a table. Everything is functioning properly, however, there are instances where the "mat-select" within the "mat-paginator" starts behaving strangely. This iss ...

Missing Directory Issue Upon Deploying Node.js App on Google App Engine

I have a Node.js web application built using TypeScript and Koa.js that I am looking to deploy on Google App Engine. The code has already been transpiled into JavaScript and is stored locally in the ./dist/src/ directory. Essentially, I only need to depl ...

Uncertainty surrounding dynamic bootstrapping in @NgModules

After successfully installing rc7, my module and component are functioning as expected. Now, I am looking to utilize it on a webpage by only bootstrapping modules and components if the current page contains the necessary selector. Although I have declare ...

The 'prop' property is not found within the 'IntrinsicAttributes & CustomComponentProps' type

I developed a custom module with an interface for props, extending props from a file called /types/SharedProps.d.ts. However, when I import this module into a sample project, the extended props are not included in the component. Below is how the module&apo ...

Exploring the Flow of Angular 5 HttpInterceptor

Implementing HttpInterceptor in one of my Angular applications to display a spinner for every request has been successful. However, I have encountered an issue with displaying an Error modal using a notificationService that utilizes SweetAlert. The code sn ...

Modify FrameColor of Material UI Inputs when Reset button is clicked

When using Angular Material UI in the Registermenu, I am facing an issue where clicking on the reset button deletes the content but leaves the red frames unchanged. Can anyone provide assistance with this problem? Thank you. Screenshot Here is the code f ...