Kirill
Kirill

Reputation: 217

angular 4 fetching nested json

How can I access nested json? I have the following file:

{
    "user1": {
        "name": "john",
        "surname": "johnsson"
    },
    "user2": {
        "name": "Jacob",
        "surname": "Jacobsson"
    }
}

and so on. I need to make a table from this JSON data with fields name and surname with. How can I do this? I wrote the following code: users.service.ts

export class UsersService {
    private _url: string = '../assets/users.json';

    constructor(private _http: Http) {
    }

    getUsers() {
        return this._http.get(this._url).map((response: Response) =>
            response.json());
    }
}

and the users.component

export class UsersComponent implements OnInit {
    users = [];

    constructor(private _usersService: UsersService) {
    }

    ngOnInit() {
        this._usersService.getUsers().subscribe(resUsersData => this.users = resUsersData);
        console.log(this.users);
    }
}

then I just want to see my result using {{users}} in users.component.html but I see just [object Object]. So I obviously can't access anything else and getting the error.

Upvotes: 2

Views: 5468

Answers (4)

Stephen R. Smith
Stephen R. Smith

Reputation: 3400

The first thing you want to do is flatten your JSON data file:

[{
    "name": "John",
    "surname": "Johnsson"
}, {
    "name": "Jacob",
    "surname": "Jacobsson"
}]

You have named the file users.json, so you've already described that it will contain an array of user objects, which means there's no need to carry that level of hierarchy again in the file (user1, user2), in fact that makes them harder to get at. Your users file should be a single level array of objects, each with a name and surname property.

Notice also that the entire JSON block is wrapped as an array [{ }].

Second, your service:

export class UsersService {
    private _url: string = '../assets/users.json';

    constructor(private _http: Http) {
    }

    getUsers(): Observable<Response> {
        return this._http.get(this._url)
               .map(response => response.json())
    }
}

I make sure I type everything I can, as it makes it clearer when reading the code what types are expected, and the IDE can catch type mismatches for you, which makes debugging easier.

Then the component:

export class UsersComponent implements OnInit {
users: any;

constructor(private _usersService: UsersService) {
}

    ngOnInit() {
        this._usersService.getUsers()
            .subscribe(response => {
                this.users = response;
                console.log('Returned Users:', this.users);
        });
    }

If you console.log this.users outside of the subscription, then the console statement will execute before the service has resolved the data, and you'll get 'undefined', even though the data has come back, it's just been assigned to your variable after you logged it out. Always, with subscriptions, log out your data in the .subscribe block.

Now what you should have is this.users which contains an array of 2 user objects, each with a name and surname property, and you can iterate over those in the template with an *ngFor

  <ul>
    <li *ngFor="let user of users">{{user.name}}, {{user.surname}}</li>
  </ul>

Upvotes: 3

Mahesh Bhattarai
Mahesh Bhattarai

Reputation: 752

{
    "users": [{
        "name": "john",
        "surname": "johnsson"
    },{
          "name": "Jacob",
        "surname": "Jacobsson"
      }],
}

then you can access

Upvotes: 0

Mahesh Bhattarai
Mahesh Bhattarai

Reputation: 752

your data format should be

   {
    "user": [{
        "name": "john",
        "surname": "johnsson"
    },{
        "name":"aish",
         "surname":"johnshon"
      }]
}

then you can use foreach to access all result

Upvotes: 0

CozyAzure
CozyAzure

Reputation: 8468

Your response is an Object, NOT an array. You will need to transform your response into an array, and then you can use *ngFor in your html table.

You can use Object.keys to iterate through the keys. Use .map() to return an array.

ngOnInit() {
    this._usersService.getUsers().subscribe(
        resUsersData =>
            //resUsersData is an Object, not an array. Transform it.
            this.users = Object.keys(resUsersData).map(key => resUsersData[key])
    );
    console.log(this.users);
}

Now you can use {{users}} in your *ngFor in your tables.

Upvotes: 2

Related Questions