skip to Main Content

I am learning Angular (version 8) and stuck with RxJS. Precisely, I am unable to read a particular key from an Observable.

Here is my User interface:

export interface User {
  id: Number;
  email: String;
  first_name: String;
  last_name: String;
  avatar: String;
}

Then in users.service.ts, I have a method called getUsers()which receives data from an API call (https://reqres.in/api/users). The response JSON looks like this:

{
page: 1,
per_page: 6,
total: 12,
total_pages: 2,
data: [
{
id: 1,
email: "[email protected]",
first_name: "George",
last_name: "Bluth",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"
},
{
id: 2,
email: "[email protected]",
first_name: "Janet",
last_name: "Weaver",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
},
{
id: 3,
email: "[email protected]",
first_name: "Emma",
last_name: "Wong",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"
},
{
id: 4,
email: "[email protected]",
first_name: "Eve",
last_name: "Holt",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
},
{
id: 5,
email: "[email protected]",
first_name: "Charles",
last_name: "Morris",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
},
{
id: 6,
email: "[email protected]",
first_name: "Tracey",
last_name: "Ramos",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
}
]
}

The users.service.ts file looks like this:

import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Observable } from "rxjs";

import { User } from "../models/user";

const httpOptions = {
  headers: new HttpHeaders({ "Content-Type": "applicaiton/json" })
};

@Injectable({
  providedIn: "root"
})
export class UsersService {
  private getUsersUrl: string = "https://reqres.in/api/users";
  constructor(private http: HttpClient) {}

  // We have casted the observable into an array of type User
  getUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.getUsersUrl);
  }
}

The Observable returns the entire JSON response. I am trying to read the users array from this response in my component.

ngOnInit() {
    this.loaded = false;
    setTimeout(() => {
      this.usersService.getUsers().subscribe(cards => {
        // How do I read the "data" key in cards?
        this.users = cards.data; /* Error */
        this.loaded = true;
        console.log(this.users);
      });
    }, 2000);
  }

Getting the following error:

ERROR in src/app/components/main/main.component.ts(21,28): error TS2339: Property ‘data’ does not exist on type ‘User[]’. [Makes sense as it is not defined in the User interface]

If I change this.users = cards.data; to this.users = cards; and then do a console.log, I see the entire JSON response from above. I am trying to display a list of users on my UI.

Please advise.

2

Answers


  1. Your getUsers() function is returning an array of type ‘User’, a type that doesn’t have a property of ‘data’ on it. That is why you are getting the error.

    Essentially your json structure doesn’t match the structure of the type you are trying to use.

    To remedy this one solution would be to create a new type like:

    export interface Page {
      page: number,
      per_page: number,
      total: number,
      total_pages: number,
      data: User[]
    }
    

    Then return that from your service:

     getUsers(): Observable<User[]> {
        return this.http.get<Page>(this.getUsersUrl);
      }
    

    Now you should be able to access cards.data in your subscription.

    Login or Signup to reply.
  2. If you want to return an observable of User[], you can use the map operator to return data :

    getUsers(): Observable<User[]> {
      return this.http.get(this.getUsersUrl).pipe(map((result:any)=>result.data));
    }
    

    and subscribe to observable like:

    this.usersService.getUsers().subscribe(users=> {
        this.users = users;
        this.loaded = true;
        console.log(this.users);
      });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search