0

I tried to get user information from randomuser.me server and I tried to display these user data inside the html page. This is what I tried to do for this;

randomuser.page.ts

    import { Component, OnInit } from '@angular/core';
    import { HttpClient } from '@angular/common/http';

    @Component({
      selector: 'app-randomuser',
      templateUrl: './randomuser.page.html',
      styleUrls: ['./randomuser.page.scss'],
    })
    export class RandomuserPage implements OnInit {

        public randomUser = []; 

        constructor(private httpClient: HttpClient) { }

        get_users() {
            this.httpClient.get("https://randomuser.me/api/?results=1")
                .subscribe((res) => {
                    console.log(res);
                    this.randomUser[0] = res;
            });
        }
      ngOnInit() {
      }
    }

randomuser.page.html

    <ion-header>
        <ion-toolbar>
            <ion-title>randomuser</ion-title>
        </ion-toolbar>
    </ion-header>

    <ion-content>
        <button (click)="get_users()">GET /Users</button>
        <ion-list>
            <ion-item *ngFor="let ru of randomUser">
                <h2>{{ru.gender}}</h2>
                <p>{{ru.email}}</p>
            </ion-item>
        </ion-list>
    </ion-content>

I succedded to get data and displayed in the console output but I couldn't show this on html part. How can I solve this issue?

2
  • can you post a sample response data ? Commented May 23, 2019 at 8:07
  • It's a public api, so you can try yourself :) Commented May 23, 2019 at 8:20

5 Answers 5

2

Response from api is an object with a results property that stores requested data into array format.

So, you must store res.results to display your data with your html in this way:

this.randomUser = res.results;

Hope it helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Should be "results" btw, in plural :)
Correct, sorry for that.
0

Update: https://stackblitz.com/edit/angular-bbiy2h

Because

let x = [];
x[0] = 'foo';

means you are assigning a property with the name "0".

Array.push actually extends the array by one item. That means [0] would not be a property access, but an index access. But this only happens after the array contains the index.

let x = [];
x.push('foo');
x[0] = 'bar'

would change the content of the array at index [0].

Now to the angular detection: In the first example, this detection would not work. You are using *ngFor which listens for the array and the concerning indices. When assigning the property [0] it would not detect anything, since the array is bound but there's no binding on property [0].

With the second one, it would work, because the array does not change, but the content of one of the indices does. So angular updates it's bindings.

Furthermore, as written in meysam faghfouri's post, you need to take a detailed look at the api response: It returns an object, containing a results property. And only there you got your users. So it is needed to access the users list with

res.results

Instead of just

res

.

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-randomuser',
  templateUrl: './randomuser.page.html',
  styleUrls: ['./randomuser.page.scss'],
})
export class RandomuserPage implements OnInit {

    public randomUser: any; // Change this to "any" if only one user is used. or:
    // public randomUser = []; // leave it as is and see below

    constructor(private httpClient: HttpClient) { }

    get_users() { // UPDATE: Give this a proper name.
        this.httpClient.get("https://randomuser.me/api/?results=1")
            .subscribe((res: { results: any[] }) ) => {// UPDATE: Define the structure of the data! Otherwise this just will be Object!
                console.log(res);
                this.randomUser = res.results[0]; // only use the first user, or
                // this.randomUser = res.results; // use all entries returned by the api.
        });
    }
  ngOnInit() {
  }
}

When using only one user, you could also remove the *ngFor and bind to randomUser directly:

<ion-header>
    <ion-toolbar>
        <ion-title>randomuser</ion-title>
    </ion-toolbar>
</ion-header>

<ion-content>
    <button (click)="get_users()">GET /Users</button>
    <ion-list>
        <ion-item>
            <h2>{{randomUser.gender}}</h2>
            <p>{{randomUser.email}}</p>
        </ion-item>
    </ion-list>
</ion-content>

3 Comments

I don't know why but I couldn't use .result property. I mean there is no .result property when pressed . :) I use latest version of angular and ionic and mybe something change in this version. I tried all of this before and also search Google and find different example. somebody uses .map for parse these data and some use your suggest but I don't have .map for httpclient or .result
You mean your IDE is complaining? That's because httpclient.get returns a response of type Object. This one doesnt have the property "results". But the data inside has, so give it a proper type. I updated the post and added a working stackblitz.
Post update is done now. Sorry, forgot to do it before :D
0

You have set data like this "this.randomUser[0] = res " but you used it as "let ru of randomUser". you should change your code to "this this.randomUser = res" in Component.

4 Comments

this.randomUser is used into a ngFor directive that iterates the array.
Aight, but this could be one solution though, since you are (by code) only intending to use one user.
@lorenago yes it is used in ngFor directive but the problem is here "this.randomUser[0] = res" if "res" is an array then assigning it to index 0 doesn't make sense
@meysam, res is an object.
0

Your problem is, that Angular only updates the DOM when references change. Simple Array item changes don't change it's reference. You can use

detectChanges()

or simply do real changes by updating the arrays reference

this.randomUser = ...this.randomUser

after you assigned some new items to the array

And here some side notes: You should wrap your httpClient into a apiService which returns an observable or promise. Further you could return a complete new array in this observable containing the new elements. Doing it that way you could use this observable directly in your html

{{ myObservable | async }}

2 Comments

That is not fully true: All asynchronous operations coming from the framework and environment are wrapped into Zone.js. That means that angular will automatically get the hang of many changes. httpClient operations are one of them. The only thing you need to take care of is if you are using non-zoned methods and objects. Then you need to make sure that you detect the changes yourself by triggering a digest cycle implicitly.
This btw also includes operations created within the angular cycle with the following objects: Promise, HttpClient, EventListeners from DOM and many more. blog.thoughtram.io/angular/2016/02/01/…
0

Try this:

randomuser.page.ts

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-randomuser',
  templateUrl: './randomuser.page.html',
  styleUrls: ['./randomuser.page.scss'],
})
export class RandomuserPage implements OnInit {

    public randomUser = []; 

    constructor(private httpClient: HttpClient) { }

    get_products() {
        this.httpClient.get("https://randomuser.me/api/?results=1")
            .then((res) => {
                console.log(res);
                this.randomUser = res;
        });
    }
  ngOnInit() {
  }
}

or

randomuser.page.html

<ion-header>
    <ion-toolbar>
        <ion-title>randomuser</ion-title>
    </ion-toolbar>
</ion-header>

<ion-content>
    <button (click)="get_users()">GET /Users</button>
    <ion-list>
        <ion-item *ngFor="let ru of randomUser[0]">
            <h2>{{ru.gender}}</h2>
            <p>{{ru.email}}</p>
        </ion-item>
    </ion-list>
</ion-content>

7 Comments

if I use randomUser[0] in html part I get following error
"Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays."
can you please share your sample response object.
and if I tried to chance this.randomUser[0] = res to this.randomUser = res; I couldn't compile my code and get and error, error TS2322: Type 'Object' is not assignable to type 'any[]
This is what I get from console output: 0: Object { gender: "male", email: "[email protected]", phone: "(824)-658-4841", … }
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.