Perché la mia lista Angular non si aggiorna dopo push? [ChangeDetection]

👤 Iniziato da @adalbertovilla86
📅 16/02/2026 12:01
📁 Programmazione 🌐 IT
Avatar di adalbertovilla86
Ragazzi, ho un problema che mi fa saltare dalla sedia! In un componente Angular (versione 16), quando aggiungo oggetti a un array con .push(), la UI non si aggiorna. Ho già provato a usare la spread syntax per reimpostare l'array (tipo this.items = [...this.items]), ma funziona solo a volte. Ecco il codice:

```typescript
export class ListComponent {
items: Item[] = [];

addItem(newItem: Item) {
this.items.push(newItem);
// Tentativo fallito: this.items = [...this.items];
}
}
```

Nel template uso *ngFor="let item of items". La ChangeDetectionStrategy è impostata su Default. Ho notato che l'aggiornamento avviene solo dopo eventi come click o timeout. Qualcuno ha affrontato questo casotto? Suggerimenti concreti per forzare il refresh della view senza ricorrere a ChangeDetectorRef manuale ogni volta?
Avatar di marinoriva36
Ehi adalbertovilla86, capisco la frustrazione - Angular e il change detection a volte sono davvero un rompicapo! La tua soluzione con `[...this.items]` è quasi corretta, ma va applicata **dopo** la push, non al posto giusto:

```typescript
addItem(newItem: Item) {
this.items.push(newItem);
this.items = [...this.items]; // Forza il cambio di riferimento
}
```

Se però già lo fai e funziona solo a intermittenza, ecco due punti critici da controllare:
1. **ChangeDetectionStrategy**: anche se è Default, verifica se *componenti padre* hanno OnPush. Se sì, gli input devono cambiare riferimento per propagare l'update.
2. **Zona d'azione**: se `addItem()` è chiamato da eventi esterni (es. callback di librerie terze), Angular non rileva il cambiamento. Usa `NgZone.run()`:

```typescript
constructor(private ngZone: NgZone) {}

addItem(newItem: Item) {
this.ngZone.run(() => {
this.items = [...this.items, newItem]; // Ricrea l'array e aggiorna la reference
});
}
```

Alternative efficaci:
- Usa librerie come **immer** per gestire l'immutabilità senza boilerplate
- Se l'array è grande, prova `trackBy` in `*ngFor` per ottimizzare i renders

Se il problema persiste, condividi uno stackblitz che riproduce l'errore - ci diamo un'occhiata insieme! 💪
Avatar di adalbertovilla86
Ehi marinoriva36, hai ragione sul rompicapo! 😅 Il punto 2 è un fulmine: uso una callback esterna e *non* avevo pensato a `NgZone.run()`! Provo subito a spostare l'assegnazione dell'array lì dentro.

Controllo anche gli OnPush nei padri (c'è un componente wrapper che potrebbe bloccarmi). Se persiste, ti aggiorno con lo stackblitz. Per gli array enormi, ottimo spunto su `trackBy`!

Grazie mille per gli esempi chiari e le alternative - mi hai salvato dalle furie del change detection 🔥

La Tua Risposta

💬

Vuoi partecipare alla discussione?

Accedi o registrati per scrivere la tua risposta e unirti alla conversazione!