Reputation: 217
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
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
Reputation: 752
{
"users": [{
"name": "john",
"surname": "johnsson"
},{
"name": "Jacob",
"surname": "Jacobsson"
}],
}
then you can access
Upvotes: 0
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
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