0
votes

I was looking for any good solution of my problem, but did not find anything correct. If my problem is a duplicate I have to be blind... and sorry for that.

So I have a little task to do which is not hard because I did it with API which I had before.

Example:

[{"id":1,"first_name":"Abdul","last_name":"Isakov",},
{"id":1,"first_name":"Abdul","last_name":"Isakov",}]

But now I am working with little different API, which makes me a problem to displaying the list of users.

I have to display a list of users with Angular 6 using an API which you can find below.

https://reqres.in/api/users?page=2

example:

{"page":2,"per_page":3,"total":12,"total_pages":4,"data": 
[{"id":4,"first_name":"Eve","last_name":"Holt"}, 
{"id":5,"first_name":"Charles","last_name":"Morris"]}

As you see here I have something like that

{ number, number, number, number, array[]}

The main problem is that I can not use ngFor to display information about users from "data". This the main quest which I have to do...

Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

I was working with https://angular.io/api but there is an easier way to display the list.

My code below:

user.ts

export interface User {
  page: number,
  per_page: number,
  total: number,
  total_pages: number,
  data: Array<any>
}

users.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { User } from './user';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class UsersService {

  readonly urlApi = 'https://reqres.in/api/users?page=2';
  users: Observable<User[]>;
  constructor(private http: HttpClient) { }
  getUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.urlApi);
  }
}

users.component.ts

import { Component, OnInit } from '@angular/core';
import { User } from '../../user';
import { UsersService } from '../../users.service';

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

export class UsersComponent implements OnInit {
  users: User[];
  constructor(private usersService: UsersService) { }
  ngOnInit() {
    this.getUsers();
    console.log(this.users);
  }
  getUsers(): void {
    this.usersService.getUsers()
      .subscribe(users => console.log(this.users = users));
  }
}

and the last: users.component.html

<div class="container text-center">
<div class="users">
    <div class="row">
        <h2 class="col-12 users__title">Users List</h2>
    </div>
    <div class="row">
        <ul class="col-12 users__form">
                <li class="list-group-item" *ngFor="let user of users">
                    <div class="row">
                        <div class="col-6">
                            <img class="users_form--image">
                        </div>
                        <div class="col-6 users__form__information">
                            <p>{{user.data}}</p>
                        </div>
                    </div>
                </li>
        </ul>
    </div>
</div>
</div>

I need to make another variable which could store objects of "data or something like that.

Sorry for spam. Thank you for helping!

3
in your html, try *ngFor="let item of users.data" and <p>{{item.first_name}}</p>.rhavelka
I have tried it before. *ngFor="let user of users.data" error: "Identifier 'data' is not defined. 'Array' does not contain such a member" this is funny... it works but still i see errors in consolePiotr Gudalewicz
Please note that in English, the word I must be upper case when referring to yourself. I took the liberty of editing, but just a reminder for the future.Heretic Monkey
ok, if you are getting an error but it is still working, then I am guessing users.data is undefined.undefined which should give an error. Then in the html it throws the error until it is populated. Phix's answer solves that problem but removing a possible undefined of undefined reference.rhavelka

3 Answers

1
votes

The array you want is in the result's data property, so you'll need to iterate over that or just assign right away:

getUsers(): void {
  this.usersService.getUsers()
    .subscribe(result => this.users = result.data);
}
0
votes

Use a map to extract the propertie DATA from your API

getUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.urlApi).pipe(map(res => {return res['data']}));
}
0
votes

You should change interface

export interface User { id: name, first_name: string, last_name: string }

export interface Entity { page: number, per_page: number, total: number, total_pages: number, data: Array<User> }

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