Child component in Angular fails to recognize changes

When I update the product object from the parent component, the child component does not seem to detect the change and fails to update accordingly.

product.ts

export interface Product { 
    productId: number;
    productName: string;
    lastUpdated: string;
    orders: Array<Order>
}

order.ts:

export interface Order { 
    orderId: number;
    payments: Array<Payment>
}

payment.ts:

export interface Payment { 
    paymentId: number;
    amount: Array<number>
}

parent.component.html

<product-details [(product)]="product1" (refreshProduct)="refreshProduct()"></product-details>

parent.component.ts

product1: Product = null;

refreshProduct() {
      this.sub = this.productService.getTheLatestOrders().subscribe(
        (data) => {
          this.product1.lastUpdated = data.lastUpdated;
          this.product1.orders.forEach(order => {
            let latestOrderData = data.orders.find(d => d.orderId == order.orderId);
            if(latestOrderData) {
              order.payments = latestOrderData.payments;
            }
          });
          // this.product1 = JSON.parse(JSON.stringify(this.product1)); --> It works if I add this
      });
    }
  }

product-details.component.html (child component)

<button id="refresh" name="refresh" (click)="refresh()" />
Last Updated : {{product.lastUpdated}}

<ng-container *ngFor="let order of product.orders">
      <ng-container *ngFor="let payment of order.payments">
             {{payment.date}} - {{payment.amount}} 
      </ng-container>
</ng-container>

product-details.component.ts (child component)

@Input('product') product: Product;
@Output() refreshProduct = new EventEmitter<any>();

refresh() {
  this.refreshProduct.emit();
}

I attempted to explicitly declare

changeDetection: ChangeDetectionStrategy.Default
, but it did not solve the issue.

As shown in the code, adding

JSON.parse(JSON.stringify(this.product1));
solves the problem. It appears that creating a new object is necessary for change detection to function properly. Using the spread operator (object.assign) can accomplish this task, but updating the product inside the refreshProduct() method using the spread operation remains unclear.

The potential solution could look like:

this.product1 = {...this.product1, 
            lastUpdated: data.lastUpdated,
            orders: .... // --> Not sure how to loop through orders and update the payments

          };

EDIT: I believe I have figured it out.

this.product1 = {...this.product1, 
            lastUpdated: data.lastUpdated,
            orders: this.product1.orders.map((order) => {
                     let updatedOrder = data.orders.find(o => o.orderId == order.orderId);  
                     return {...order, order.payments: updateOrder.payments};

                    })
          };

If you have any better solutions available, please let me know.

Answer №1

Here is a suggested approach:

updateProduct() {
      let newProduct: Product = {};
      this.subscription = this.productService.fetchLatestOrders().subscribe(
        (response) => {
          newProduct.lastUpdated = response.lastUpdated;
          newProduct.orders.forEach(order => {
            let updatedOrderData = response.orders.find(d => d.orderId == order.orderId);
            if(updatedOrderData) {
              order.payments = updatedOrderData.payments;
            }
          });
          this.currentProduct = newProduct;
      });
    }
  }

This method ensures that the product is always updated with the latest values.

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 Zip file generated in memory is experiencing corruption

I'm encountering an issue while attempting to serve a zip file generated in memory by Flask to a JavaScript front-end. However, the downloaded file appears corrupted and I am unsure of what mistake I may be making. @app.route('/route') def ...

How can one effectively restrict the number of tags allowed in a WYSIWYG editor?

It is not enough to limit the tags in a WYSIWYG editor by excluding buttons, as I can still copy page content and paste it into the editor, which it will accept! I am looking for a solution to restrict the allowed tags. For example, I admire how Stack Ove ...

Webpack resolve.alias is not properly identified by Typescript

In the Webpack configuration, I have set up the following: usersAlias: path.resolve(__dirname, '../src/pages/users'), In my tsconfig.json, you can find: "baseUrl": ".", "paths": { "usersAlias/*": ["src/pages/users/*"], } This is how the cod ...

Automating the scrolling function in Angular 2 to automatically navigate to the bottom of the page whenever a message is sent or opened

In my message conversation section, I want to ensure that the scroll is always at the bottom. When the page is reopened, the last message should be displayed first. HTML: <ul> <li *ngFor="let reply of message_show.messages"> ...

The issue with the autoresize feature in the tinymce plugin arises when trying to delete HTML img content using the backspace

When using the tinymce editor with the autoresize plugin enabled, I have noticed that it works correctly with text. However, there is an issue when inserting HTML content via execCommand. For example, if I insert the following code: <div> < ...

Legend in AMCharts 5 remains visible even after deleting the chart

I integrated an AMCharts 5 chart into my Angular application that requires removal upon a specific action. However, even after deleting the chart, the legend tooltips continue to be displayed. Below is the code snippet used to generate the chart : this ...

increase the variable based on the count of clicks

I need some assistance with the code snippet below: Javascript: var counter = 0; var totalItems = 8; var remainingItems = $num - totalItems; if (remainingItems == 22) { $('#next').click(function(e) { e.preventDefault(); cou ...

Error: The call stack has reached its maximum size

I keep encountering an error in my Chrome console that says 'Uncaught RangeError: Maximum call stack size exceeded' and I suspect it has something to do with the setInterval method I'm using in my JavaScript file. The setInterval method is ...

The global installation of grunt was unsuccessful and I am unable to locate it on npmjs.org

Can anyone help me troubleshoot this error I'm encountering while running npm install? I usually don't have issues installing libraries globally, but I can't seem to find grunt on npm install -g grunt npm ERR! Error: Not found: grunt@&apos ...

Issues with appending new rows using JavaScript

I'm facing an issue with adding rows to the table using this code and I can't seem to find a solution. function add() { document.getElementById("popup").style.display = "block"; document.getElementById("add").addEventListener("click", func ...

the input parameter is not being passed to the component

I need assistance with creating an inline input edit component. The component is loading correctly, but it seems like the @Input() variables are always returning undefined. index.html ... <app-inlineinput [name]="username" [fi ...

Are npm dependencies lacking (despite being expected to be present)?

It seems like I might be missing something important here. Upon attempting to execute npm install on a current project, I encounter the following error (from npm-debug.log): 76 error Windows_NT 6.1.7601 77 error argv "C:\\Program Files\&bs ...

Angular query parameters are similar to httpd_query_params

Currently, I am utilizing an API with functional tests and I am confident in receiving a good response using the following URL: /api/v1/investors?vehicle%5B0%5D=4 Decoded equivalent URL: /api/v1/investors?vehicle[0]=4 I am employing Angular to make my ...

Issue with displaying Highcharts graph on JSP page

My attempt to display a graph by invoking a function has hit a roadblock. The chart fails to appear on my jsp page, even though the exact same code works when tested in JSFiddle. In addition to that, I have included the following libraries: <script sr ...

What is the best way to adjust the size of an image to the viewing area

In my application, users can take photos either horizontally or vertically. These images are then displayed in a gallery on a webpage, and when clicked on, they expand using a Modal. My issue arises with horizontal images looking smaller than vertical one ...

Encountering a problem with Angular 2 router functionality

As a beginner in programming with Node.js, Angular2, and Typescript, I decided to explore the Angular forms and Angular router to enhance my application with new pages. Utilizing Material Design Lite (MDL) for material components in my application, I encou ...

Ways to perform a jQuery selection beginning with a pre-existing jQuery object

When working with Vanilla JavaScript, you can select an element from the DOM using the following method: let element = document.querySelector('[css selector]'); Once you have the element selected, you can further target elements within it using ...

Unable to change the color of the RaisedButton component in Material-UI

Struggling to alter the color of the material-ui RaisedButton with inline style customization using backgroundColor: '#fb933c', yet it continues to display the default color. ...

Dynamic font sizing in CSS allows text on a webpage to

I am working on creating a dynamic screen using AngularJS. Within this screen, there are objects with a specific size: .item { margin: auto; margin-bottom: 10px; width: 11vw; height: 11vw; text-overflow: ellipsis; overflow: hidden; } These i ...

"Information in the table derived from the contents of the provided URL

I have created a JavaScript function that displays a table when a user hovers over specific text on a website. Currently, the table's content is hardcoded with a few words for debugging purposes and it appears as expected. The HTML code for the cont ...