Is OnPush Change Detection failing to detect state changes?

Curious about the issue with the OnPush change detection strategy not functioning properly in this demonstration.

My understanding is that OnPush change detection should activate when a property reference changes. To ensure this, a new array must be set each time like so:

    this.periodData$.subscribe((pd) => {
      this.periodData = [...pd];
    });

The template that displays periodData appears as follows:

<div *ngFor="let p of periodData">{{p}}</div>

The value of periodData is modified by the selection control in the demo.

While we can observe the changes through logging, the template does not reflect these updates. It works fine if change detection is left at default settings.

Any ideas on how to resolve this?

Answer №1

To ensure proper change detection after updating the periodData, utilize the ChangeDetectorRef.

import {
  ChangeDetectionStrategy,
  Component,
  Input,
  OnInit,
  ViewEncapsulation,
  ChangeDetectorRef,
} from '@angular/core';
import { AsyncPipe, NgFor } from '@angular/common';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-detect',
  imports: [NgFor, AsyncPipe],
  standAlone: true,
  template: `
 <div *ngFor="let p of periodData">{{p}}</div>
  `,
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DetectComponent implements OnInit {
  @Input()
  periodData$!: Observable<any[]>;
  periodData: any[] = [];

  constructor(private cdr: ChangeDetectorRef) {}

  ngOnInit() {
    this.periodData$.subscribe((pd) => {
      console.log(`Updated Period Data is ${JSON.stringify(pd)}`);
      this.periodData = [...pd];
      this.cdr.detectChanges();
    });
  }
}

Answer №2

Aha! I finally discovered the solution in this thread. Essentially:

It's important to note that object changes do not activate on-push change detection; this rule only applies to component inputs.

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

What are the steps for incorporating React into an existing website?

Currently, I have a website built with Express and I am looking to incorporate React into specific pages. What is the most effective method to integrate it while utilizing all the resources available through create-react-app? I understand that I can manua ...

Utilizing Google APIs to split a route among multiple locations

I am facing a scenario where A laundry company operates from one shop location. The laundry company has 3 trucks available (n trucks). The laundry company needs to deliver washed clothes to multiple locations (n locations). Using the Google Directions AP ...

Having trouble pinpointing the element with protractor's binding locator

<div class="apiRequestDisplay ng-scope"> <pre class="ng-binding">GET</pre> <pre class="ng-binding">v1/securityprofiles/{securityProfileID} </pre> </div> I am trying to target the specific text within v1/secur ...

Utilizing Express Session with Vue CLI in a Node.js Environment

Developing a nodejs backend for my Vue application has brought up a challenge regarding user sessions and database operations. I initially tried using express-session, but the sessions appeared as undefined in subsequent requests. How can I address this is ...

`What is the best way to employ the Return statement in programming?`

Trying to grasp the concepts of functions and methods has been a challenge for me. I often find myself confused about when, where, and how to use return statements in different situations. To illustrate this confusion, let's take a look at two code sn ...

React's createPortal function does not place the child element inside a container

My new to-do list app in React has a simple functionality where clicking a button should add a new item to the list. However, I am facing an issue with the createPortal method not triggering the UI to render the new item. Here's the code snippet causi ...

Is Validators.required a necessity in Angular 2?

Is there a way to dynamically require a form field based on conditions? I created a custom validator, but the conditional variables passed to it remain static. How can I update these conditional values within the custom validator function? Is it possible t ...

JavaScript Date behaving oddly

While working with Javascript, I encountered a puzzling issue involving the Date object. date1 = new Date(1970, 1, 1); date2 = new Date("1970-01-01T13:00:00.000Z"); console.log(date1.getYear()); //70 console.log(date1.getMonth()); //1 console.log(date1.g ...

Utilizing MEAN.js for uploading images

Following a tutorial on the MEAN stack, I am looking to implement an image upload feature using MongoDB on a server. Resources: Angular directive for file uploads create-spot.client.view.html <div data-ng-controller="SpotsCreateController"> &l ...

Regularly updating a book's interactive pages with turn.js technology

I experimented with generating dynamic content in turn.js using the sample provided here. This is an excerpt of the code I have written: <body> <div id="paper"> </div> </body> <script type="text/javascript"> $(win ...

Enhance your viewing experience by magnifying a specific element, all while maintaining full control to navigate

Is it possible to create a zoom effect on a webpage that focuses on one specific element while still allowing for navigation and scrolling? I have searched online for plugins like Fancybox and Zoomooz, but none of them offer the functionality I need. I sp ...

Migrating to Angular Universal for server-side rendering with an external API server

Thank you for taking the time to read my query. I have developed a project using server-side Node.js and client-side Angular 6. The purpose of the app is to provide information on cryptocurrency prices and details. I am now looking to transition my Angu ...

The layout of an Angular Material page gets disrupted when a sticky "header" with md-select options is used in combination with the md-backdrop

I designed a filter bar for a table that sticks above the table at a certain height. Everything was working smoothly until I opened the dropdown options in the md-select. This caused the md-backdrop to appear and apply inline positioning to the body, shift ...

Issue with bootstrap 4 CDN not functioning on Windows 7 operating system

No matter what I do, the CDN for Bootstrap 4 just won't cooperate with Windows 7. Oddly enough, it works perfectly fine on Windows 8. Here is the CDN link that I'm using: <!doctype html> <html lang="en> <head> <!-- Req ...

Updating parent data when new data is added in child component in React

I'm just starting to learn React and I've been reading a lot about updating children components when the parent component is updated, but I haven't come across much information about the opposite scenario. Currently, I have a parent compone ...

Prevent the execution of a post request function depending on the promise result?

When I handle a POST request in express, I am required to retrieve data from a mongoDB cluster and then respond accordingly based on the retrieved response. app.post('/api/persons', (req, res) => { const data = req.body; if (!data.name || ...

What are the steps to successfully deploy a static website created with Next.js on Vercel?

Using the Next.js static site generator, I created a simple static site that I now want to deploy on Vercel. However, I keep encountering an error during the build process. While I have successfully deployed this site on other static hosting platforms befo ...

Ways to remove redundant code from multiple service calls

Within my DataService, I have set up an observable for various API calls. I am looking to streamline the process by creating a reusable block of code to be used in each HTTP request. export class DataService { constructor( private http: HttpClient, ...

The jQuery element selection feature is not functioning

Within my HTML file, there lies a table with an empty tbody that is dynamically filled by jQuery once the document is fully loaded. The content of the table body is generated using a PHP script, where jQuery fetches the data via a simple GET request. Belo ...

The API response appears to be a successful 200 status code, however the actual result is a

I'm currently working with a VUEJS / VUEJS Resources code snippet that retrieves data from an API service. fetchData: function(name){ var self = this; self.$http.get('http://www.apiservice.com/', { params: { ...