Reputation: 1328
I have an Angular 2 application which contains a message feed that is an array of type IMessage
. In the OnInit
event the messages are retrieved from the server and displayed.
So far so good.
When i update the array of IMessage
using this.messagea.unshift(newMessage);
the view does not display the new message. When i loop through that same array I can see the new message is in the array and refreshing the page (and retrieve the new message from the database) also shows it.
My main component:
import { Component, OnInit } from '@angular/core'
import { IMessage } from './message.model';
import { MessageService } from './message.service';
@Component({
selector: 'messages',
template: `<message *ngFor="let message of messages" [message]="message"></message>`
})
export class MessagesComponent implements OnInit {
private messages: IMessage[] = [];
constructor(private messageService: MessageService) {
}
ngOnInit() {
this.messageService.getMessages().subscribe((newMessages: IMessage[]) => {
this.messages = newMessages;
setTimeout(() => {
let newMessage: IMessage = {
"id": 1,
"title": "TEST",
"message": "message"
};
this.messages.unshift(newMessage);
});
});
}
}
I have read about change detection in Angular but using a ChangeDetectorRef
and call its detectChanges()
or markForCheck()
functions do not update the feed with the new message.
I have noticed that when I output the messages
directly instead of calling a child component the list is updated.
template: `<span *ngFor="let message of messages">{{message.title}}</span>`
Upvotes: 0
Views: 302
Reputation: 1530
when calling messageService.getMessages()
your code might be running outside the angular. that is why when you assign values to variable it doesn't update the view.
try running code inside the angular NgZone
. after that your view will be updated successfully.
import { Component, OnInit } from '@angular/core'
import { IMessage } from './message.model';
import { MessageService } from './message.service';
import {
NgZone,
ChangeDetectorRef
} from "@angular/core";
@Component({
selector: 'messages',
template: `<message *ngFor="let message of messages" [message]="message"></message>`
})
export class MessagesComponent implements OnInit {
private messages: IMessage[] = [];
constructor(private messageService: MessageService,private zone:NgZone) {
}
ngOnInit() {
this.messageService.getMessages().subscribe((newMessages: IMessage[]) => {
this.zone.run(()=>{
this.messages = newMessages;
});
setTimeout(() => {
let newMessage: IMessage = {
"id": 1,
"title": "TEST",
"message": "message"
};
this.zone.run(()=>{
this.messages.unshift(newMessage);
});
});
});
}
}
Upvotes: 1