I have a very simple Angular2 component:
@Component({
moduleId: module.id,
selector: 'app-people',
templateUrl: 'people.component.html'
})
export class PeopleComponent implements OnInit {
people: any[] = [];
constructor(private peopleService: PeopleService) {
}
ngOnInit() {
this.peopleService.getPeople()
.subscribe(this.extractPeople);
}
extractPeople(result: any) {
this.people = result.people;
}
}
On initialization, I see that ngOnInit()
is called which calls peopleService.getPeople()
. I also see the asynchronous return which calls extractPeople()
. However, even after this.people
gets updated the component is not re-rendered. Why is this happening? Why is the change not detected?
Edit Here's some related code for additional context:
people.component.html
<tr class="person-row" *ngFor="let person of people">
<td class="name">{{person.name}}</td>
</tr>
people.service.ts
getPeople(): Observable<any> {
return this.http
.get(peopleUrl)
.map(response => response.json());
}
If I console.log(this.people)
inside PeopleComponent.extractPeople()
, I correctly get an array of people:
[
{
id: 11,
name: "John Smith"
},
...
]
However, the component is not re-rendered at this point. The view is still showing the initial value of of the people array which is empty. In fact, if I initialize the array with a couple of hard coded people, they show up correctly on the initial rendering of the component. However this list is not re-rendered when the real http data arrives! It is as if change detection is not triggering at all.
I suppose that you need to use arrow function to retain this
at this line:
this.peopleService.getPeople()
.subscribe(this.extractPeople); <=== here
This way your code should look like this:
this.peopleService.getPeople()
.subscribe((res) => this.extractPeople(res));
More information about using arrow function you can find here https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Lexical_this