Child component doesn't update param @Input
when parent component is changing the attribute.
All similar questions I have came across DO NOT solve the problem.
example: The Parent Variable is not updating in the child Component in Angular
or ... https://pretagteam.com/question/angular-child-component-not-updating-after-change-detection
The first time it is created, the property is shared. But when I make a modification from the [(ngModel)]
directive (found in the parent), it does NOT propagate the changes to the child component, and therefore the child component does not receive the updated data. (It stays with the previous ones, the ones provided at the beginning).
This is the parent component:
/**
* Created by cnoe la bestia on 13/12/2021
**/
import {Component, OnInit} from '@angular/core';
import {Pedido, Status} from "../shared/“app.model";
import {ActivatedRoute, Router} from "@angular/router";
import {DataService} from "../shared/data.service";
import {ClienteApiRestPedidosService} from "../shared/cliente-api-rest-pedidos.service";
@Component({
selector: 'createPedidoComponent',
templateUrl: './createPedido.component.html',
styleUrls: ['./crearPedido.component.css']
})
export class FatherComponent implements OnInit {
p : string = "p"
pedido: Pedido ={
deliveryAddress: "",
deliveryCity: "",
deliveryPerson: "",
status: Status.Ordered,
} as Pedido;
...
}
and this is the html (part):
...
<fieldset >
<div >
<label for="idSeller">idSeller</label>
<input type="test"
[(ngModel)]="pedido.idSeller" name="idSeller" >
</div>
</fieldset>
<fieldset >
<div >
<label for="expectedDeliveryDate">expectedDeliveryDate</label>
<input type="test"
[(ngModel)]="pedido.expectedDeliveryDate" name="expectedDeliveryDate" >
</div>
</fieldset>
<br>
<LineaPedidoComponent [pedido] = "pedido" [cabecera] = "cabecera" [llamada] = "p" > </LineaPedidoComponent>
<br>
...
The child component ts:
/**
* Created by cnoe la bestia on 20/12/2021
**/
import {Component, Input, OnInit} from '@angular/core';
import {LineaPedido, Pedido} from "../shared/“app.model";
import {ClienteApiRestPedidosService} from "../shared/cliente-api-rest-pedidos.service";
import {ActivatedRoute, Router} from "@angular/router";
@Component({
selector: 'LineaPedidoComponent',
templateUrl: './LineaPedido.component.html',
styleUrls: ['./LineaPedido.component.css']
})
export class LineaPedidoComponent implements OnInit {
@Input() pedido : Pedido
@Input() cabecera : boolean | undefined
@Input() llamada :string
id !: number
json: string
constructor(private ClienteApiRestPedidosService: ClienteApiRestPedidosService, private ruta: ActivatedRoute,
private router: Router) {
}
...
}
Any ideas?
CodePudding user response:
You might try with setter and getter, or with ngOnChanges - depending on how big the Padido data actually is and how often you expect it to change, and how often other vars passed to child change. For a short look at these options, see:
https://javascript.plainenglish.io/dumb-angular-input-setter-getter-vs-ngonchanges-f30e61937926
https://dev.to/angular/angular-setters-vs-ngonchanges-which-one-is-better-4f2b
https://ultimatecourses.com/blog/detect-input-property-changes-ngonchanges-setters
CodePudding user response:
The solution is to change the detection strategy to onpush in your child
@Component({
selector: 'LineaPedidoComponent',
templateUrl: './LineaPedido.component.html',
styleUrls: ['./LineaPedido.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
CodePudding user response:
Both options that you have given me have worked for me when I have removed from my child component an "overwrite" of the attribute that we were linking. This overwriting is done by recovering an order (the tribute that we also ask for) through http.
The reason I have 2 ways to retrieve an order (http
and @Input
) is as follows:
The child component I call it from different parts, and depending on the part I call it one way or another.
This may be a bad practice, but it was a way to fix that problem quickly.
If I override the attribute when creating the child component, the binding is no longer done correctly (even if you keep modifying the attribute in the parent component).
Removing that part and leaving only for when the attribute we need from the
@Input
solves this problem. But we must also add the code of @souhail-harrati :)
Thank you very much, it works, although I do not know why when redefining the attribute (and continuing to make modifications in the parent component) it stops binding.