Search code examples
angularrxjsangular2-changedetection

Why isn't my Angular child component updating


Using Angular 14.2, I have a child component which receives an array from its parent and is supposed to show the updated array.

But it doesn't.

If I click to another page and come back to this one, the messages are displayed, so I know that they are being received by the child, just not displayed. All of the examples I've looked at say this should work, so I'm not sure what I'm missing.

Here is my code on StackBlitz: https://stackblitz.com/edit/angular-1dtcms?file=src%2Fapp.component.ts,src%2Fmain.ts. This code has the error - I see all of the console.log entries when they are received in the subscription, including that the value is added to consoleMessages array (the length increases), but the values are not shown in the JobConsole component.

RxJS Subject

There is an RxJS Subject elsewhere in my app which emits values. To simulate this on StackBlitz, I have the following code in my main.ts file:

const int = interval(3000).subscribe((n) => {
  console.log('emitting from main: ', n);
  subj$.next(n);
});

Parent Component

<job-console [msgs]="consoleMessages"></job-console>
subj$.subscribe(n => {
      console.log('received in AppComponent', n);
      this.consoleMessages = [n.toString(), ...this.consoleMessages];
      console.log('consoleMessages length: ', this.consoleMessages.length);
    });

Child Component

<div class="console">
  Messages should show here, but dont.  ???
  <div *ngFor="let item of msgs">--{{item}}</div>
</div>
@Component({
  selector: 'job-console',
  templateUrl: './job-console.component.html',
  styleUrls: ['./job-console.component.scss']
})
export class JobConsoleComponent  {

  @Input() msgs: string[] = []
 
}

Solution

  • The interval is running outside of ngZone because you have defined it outside of the Angular app. It works if you bring the interval into the component

    https://stackblitz.com/edit/angular-bagy9m?file=src%2Fapp.component.ts