Fetch information from Hal + JSON object in Angular 2

I have a spring-data-rest repository creating a hal + json object that I would like my Angular 2 frontend to accept and display.

Hal + Json object:

{
  "_embedded" : {
    "users" : [ {
      "name" : "Bob",
      "_links" : {
        "self" : {
          "href" : "http://localhost:4200/api/users/1"
        },
        "user" : {
          "href" : "http://localhost:4200/api/users/1"
        }
      }
    }, {
      "name" : "Joe",
      "_links" : {
        "self" : {
          "href" : "http://localhost:4200/api/users/2"
        },
        "user" : {
          "href" : "http://localhost:4200/api/users/2"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:4200/api/users"
    },
    "profile" : {
      "href" : "http://localhost:4200/api/profile/users"
    },
    "search" : {
      "href" : "http://localhost:4200/api/users/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 2,
    "totalPages" : 1,
    "number" : 0
  }
}

      

I have a service that makes a get request to this api.

user.service.ts:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { User } from './user.model';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map'

@Injectable()
export class UserService {

  constructor(private http: Http) {
  }

  findAllUsers(): Observable<Array<User>> {
    return this.http.get('/api/users')
      .map((response: Response) => response.json())
      .map((data: Array<User>) => {
        return data;
      });
  }
}

      

Then my user.component calls the findAllUsers method from the service.

users.component.ts

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

@Component({
  selector: 'app-users',
  providers: [UserService],
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
  users: User[];

  constructor(private userService: UserService) {
  }

  ngOnInit(): void {
   this.userService.findAllUsers().subscribe((data: Array<User>) => {
     this.users = data;
   });
  }

}

      

Finally, users.component.html:

<h4>Users:</h4>

<div *ngFor="let user of users">
  {{user}}
</div>

      

In my opinion, I am getting the error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

I am not sure how to solve this.

If I try to use the debugger before the service returns data

, then I can see my hal + json = object data

, and I can see the correct information I want from data._embedded_users

. But this cannot be mapped to User [] because it is _embedded

not a property of my user model. Do I need to do something with the Hal + Json object first?

+3


source to share


1 answer


Do I need to do something with the Hal + Json object first?

Isn't it obvious? Just fetch the data into the service

findAllUsers(): Observable<Array<User>> {
  return this.http.get('/api/users')
    .map((response: Response) => response.json())
    .map((data: any) => {
      return data._embedded.users as User[];
    });
}

      



What did you have before

.map((data: Array<User>) => {
  return data;
});

      

incorrect because you made the assumption that the data passed to the second map

is an array of users, when in fact it is the entire HAL object. Changing it to any

allows you to extract users from it.

+4


source







All Articles