3

I am learning how to use angular's new http client module. I get the error Cannot read property 'data' of undefined when I try to consume the rest api. Here's my app.html,

<div style="text-align:center">
  <h1>
    Welcome to {{title}}!
  </h1>
  <button (click)="getPosts()">Get Posts</button>
  <div *ngFor="let result of results.data">

      {{ result | json }}

    </div>
</div>

Here's my app.component.ts

import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http';

interface ItemsResponse {
  data: any[];
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
  results: any;
  // Inject HttpClient into your component or service.
  constructor(private http: HttpClient) {}
  title = 'School2College';

  ngOnInit(): void {
  }
  getPosts() {
    this.http.get<ItemsResponse>('https://reqres.in/api/users?page=3').subscribe(res =>
      this.results = res);
  }
}

Why do I get the error Cannot read property 'data' of undefined?

0

3 Answers 3

5

Since you are making a asynchronous request, initially results will be undefined, use a safe navigation operator to check if the results exists and then access the data

<div *ngFor="let result of results?.data">
      {{ result | json }}
 </div>
Sign up to request clarification or add additional context in comments.

4 Comments

what is safe navigation operator? can you explain a bit more?
Safe navigation operator can be used to prevent Angular from throwing errors, when trying to access object properties of objects that don't exist.
better way of doing what? you can alternatively use ngIF also, but this would be better option
Thanks sanjeetharan. Answer accepted. Would be nice if you vote my question up?
3

Issue is same as explained by @Sajeetharan :

Since you are making a asynchronous request, initially results will be undefined,

You can solve it by 2 ways :

1) Provide some initial value from the very beginning:

export class AppComponent implements OnInit {
    results:Array<any> = []; // code changed
    ...
    getPosts() {
        this.http.get<ItemsResponse>('https://reqres.in/api/users?page=3').subscribe(res =>
        this.results = res.data); // code changed
    }
}


<div *ngFor="let result of results">
   {{ result | json }}
</div>

2) Use safe navigation operator

<div *ngFor="let result of results?.data">
    {{ result | json }}
</div>

But it's standard practice to use the second way.

5 Comments

Thanks it worked. but i would like to access the getposts() method from a service and then subscribe back to that function from app.component.ts?
Thanks voted up. would be nice if you can vote my question.
Service : getPosts() { return this.http.get<ItemsResponse>('reqres.in/api/users?page=3').map(res => res.json()); } Component : this.postService.getPosts().subscribe(res => this.results = res.data );
Thanks for your answer :)
There is no need to convert to json with res.json
0

Cannot read property 'data' of undefined simply means that results in not defined. Put console.log or apply breakpoints and try to find out why its not getting defined. When we apply breakpoints we can find out the exact reasons why it is not getting defined. Knowing the reason is important.

Comments

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.