Reputation: 4044
I'm receiving a complicated Object sent from my Express back-end, using res.json
. (A list of members who have registered).
On the front-end, I'd like to convert the json response into an object that I can process in my template. Shouldn't I just be able to call JSON.parse() on the json response?
I've seen some proposed solutions that require the HttpClient get
call to have a generic of the type of the object to be returned, i.e. get<MyObj>
. (such as in this article Angular Http Call). Is there a way to do this without specifying in advance the return type from the get
call? (I'd like to keep the front-end implementation as light and flexible as possible, and do all the data definitions in the back-end, then use the front-end to "read" the back-end data structure. The data structure is quite complicated and long, and it would save a lot of work if I can avoid repeating the data definition in both the back and front end).
Unfortunately, I haven't found a way yet, as for instance the editor tells me that JSON.parse expects a string parameter, while my HttpClient call returns an Object.
Here's the code I have so far:
member.service.ts:
constructor(private http: HttpClient) { }
ngOnInit() {
this.getList();
}
getList(): Observable<any> {
return this.http
.get(`${this.host_url}list`,{responseType: 'json'})
}
register.component.ts
users$: Observable<Object>;
getUsers() {
this.users$ = this.member.getList();
}
register.component.html
<ul>
<ng-container *ngFor="let user of users$ | async ">
<li>
{{user | json}} <-- This gives me a string. If I use {{ user }} without the json pipe, I get an object, but can't reference its properties.
</li>
</ng-container>
</ul>
Currently, in my ngFor*
loop, I'm unable to grab the user
object and reference it's properties (i.e. user.authData[0].username
). How can I modify my code to be able to reference user
's properties in the template? Do I have to provide the data type in advance to the get
call, or is there another way?
EDIT (1): Here is some sample data returned by the {{ user | json }}
pipe:
{ "_id": "5cf1b7792ecf136bd4cddebf", "authData": [], "nameData": [], "emailData": [], "phoneData": [], "addressData": [], "companyData": [], "idData": [], "photoData": [], "memberData": [], "creditCardData": [], "__v": 0 }
{ "_id": "5cf207038e3f2551dcf4c803", "authData": [], "nameData": [], "emailData": [], "phoneData": [], "addressData": [], "companyData": [], "idData": [], "photoData": [], "memberData": [], "creditCardData": [], "__v": 0 }
{ "_id": "5d6ff6ac7046a519403c801f", "authData": [], "nameData": [], "emailData": [], "phoneData": [], "addressData": [], "companyData": [], "idData": [], "photoData": [], "memberData": [], "creditCardData": [], "__v": 0 }
{ "_id": "5d7015dddba7384d64540571", "authData": [], "nameData": [], "emailData": [], "phoneData": [], "addressData": [], "companyData": [], "idData": [], "photoData": [], "memberData": [], "creditCardData": [], "__v": 0 }
{ "_id": "5d7061fd767c8c41202f49b7", "authData": [], "nameData": [], "emailData": [], "phoneData": [], "addressData": [], "companyData": [], "idData": [], "photoData": [], "memberData": [], "creditCardData": [], "__v": 0 }
{ "_id": "5d71b9b1fa4fb10afc346323", "authData": [], "nameData": [], "emailData": [], "phoneData": [], "addressData": [], "companyData": [], "idData": [], "photoData": [], "memberData": [], "creditCardData": [], "__v": 0 }
{ "_id": "5d71bcd2fa4fb10afc346332", "authData": [], "nameData": [], "emailData": [], "phoneData": [], "addressData": [], "companyData": [], "idData": [], "photoData": [], "memberData": [], "creditCardData": [], "__v": 0 }
{ "_id": "5d71bf76fa4fb10afc34633e", "authData": [], "nameData": [], "emailData": [], "phoneData": [], "addressData": [], "companyData": [], "idData": [], "photoData": [], "memberData": [], "creditCardData": [], "__v": 0 }
{ "_id": "5d71ce7d52a93e0700f2c052", "authData": [], "nameData": [], "emailData": [], "phoneData": [], "addressData": [], "companyData": [], "idData": [], "photoData": [], "memberData": [], "creditCardData": [], "__v": 0 }
Upvotes: 0
Views: 213
Reputation: 24424
base of your data sample you can get the authData data like this
<ul>
<ng-container *ngFor="let user of users ">
<li >
user id {{user._id}} , authData length {{user.authData.length}}
userName <span *ngFor="let auth of user.authData"> {{auth.userName }}</span>
</li>
</ng-container>
</ul>
Upvotes: 1
Reputation: 1229
Of course you can; by the way Angular returns the object parsed to you; all you need is to have some object variable that contains the response; generally this object can be of type any, BUT you need first to subscribe to the response.
As an example that simulates some of your json to access it direclty
getUsers() {
this.member.getList().subscribe( resp => {
this.users = resp;
// To go through your json, you can use direct access like the following
this.users.foreach(user => {
let id = user['id']; // get the id
let authData: [] = user['authData']; // get authData list
});
})
}
And so on, this will allow you to parse dynamically instead of creating the model again in front-end. and as you have to know to access that from HTML you need to bind each object and replacing my code objects (id & authData) with them . Your code for this part in html after subscribing and assigning the result should work normally, also you can do nested loops without issue.
Upvotes: 1
Reputation: 612
member.service.ts:
getUsers(): Observable<any[]> {
return this.httpClient
.get<any[]>(`${environment.api_url}/api/users`)
.pipe(map(data => data));}
register.component.ts:
getUsers() {
this.memberService.getUsers().subscribe(data => {
this.users = data;
});
}
Then use like you wrote
<ul>
<ng-container *ngFor="let user of users$ | async ">
<li>
{{user._id}} <-- For example user name
</li>
</ng-container>
</ul>
Upvotes: 2