2

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.

3
  • Would it be possible for you to include your component metadata? Maybe the code for PeopleService, as well. Commented May 21, 2016 at 4:41
  • Can you please add some more code , atleast the service you are subscribing Commented May 21, 2016 at 5:26
  • Thanks, Mark, Carlos and Pd Farhad. Please see my edit for more context. Commented May 21, 2016 at 11:30

1 Answer 1

3

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

Sign up to request clarification or add additional context in comments.

1 Comment

Ouch, that one really hurt! Thanks, @yurzui - you nailed it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.