Search code examples
angularjstypescriptionic2httprequestionic2-providers

Ionic2, Http request don´t work correctly in starting page


I created a simple app (sidemenu template) and a provider (conexao-home.ts). In a new page called teste i created a function buscarUsuarios (associated a one button), and it calls the function getRemoteUsers in provider.

In ionViewDidLoad i put the same call to function getRemoteUsers. When the page teste starts, it makes the the call to function and read data from http, but don´t return in the back variable data read. When i make the call from button, it returns the data from the first read and show it in the page.

How to solve this?

teste.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { ConexaoHome } from '../../providers/conexao-home';

@Component({
  selector: 'page-teste',
  templateUrl: 'teste.html',
})
export class Teste {

  public users: any;
  public teste: any;

  constructor(public navCtrl: NavController, public navParams: NavParams, public conexaoServico: ConexaoHome) {

  }

  buscarUsuarios() {
    this.users = this.conexaoServico.getRemoteUsers('Pegando os usuários');
    console.log('chamando...');
    console.log(this.users);
    console.log('retornando...' + this.users);
  }

  buscar() {
    this.teste = this.conexaoServico.getRemoteTeste('testando...');
    console.log(this.teste);
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad Teste');
    //this.buscarUsuarios();
    this.users = this.conexaoServico.getRemoteUsers('Pegando os usuários');
    console.log(this.users);
  }

}

teste.html

<ion-header>
  <ion-navbar>
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Teste</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding="false">
  <button ion-button (click)="buscarUsuarios()">Pegar Dados</button>
  <br>
  <button ion-button (click)="buscar()">Pegar Dados 2</button>
  {{ teste }}
  <br>
  <ion-list>
    <button ion-item *ngFor="let user of users">
      <ion-avatar item-left>
        <img src="{{ user.picture.medium }}">
      </ion-avatar>
      <h2 text-wrap>{{ user.name.title }} {{ user.name.first }} {{ user.name.last }}</h2>
      <h3 text-wrap>{{ user.email }}</h3>
    </button>
  </ion-list>
</ion-content>

provider conexao-home.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class ConexaoHome {

  public usuarios: any;
  public areas: any;

  constructor(public http: Http) {
    console.log('Hello ConexaoHome Provider');
  }

  getRemoteUsers(tipo) {
    this.http.get('https://randomuser.me/api/?results=10').
    map(res => res.json()
    ).subscribe(data => {
      console.log(data.results);
      console.log(tipo);
      this.usuarios = data.results;
    });
    return this.usuarios;
  }

  getRemoteTeste(tipo) {
    console.log(tipo);
    return ('teste executado 2');
  }
}

Tks.


Solution

  • You cannot do like that:

    getRemoteUsers(tipo) {
        this.http.get('https://randomuser.me/api/?results=10').
        map(res => res.json()
        ).subscribe(data => {
          console.log(data.results);
          console.log(tipo);
          this.usuarios = data.results;
        });
        return this.usuarios;
    }
    

    That could finish return statement before async call has finished. Because you made an asynchronous http request via Observable. You should read more about that here

    Instead please try something like this:

    getRemoteUsers(tipo) {
        return this.http
          .get('https://randomuser.me/api/?results=10')
          .map(res => res.json())
    }
    

    Then you should use it like this:

    ionViewDidLoad() {
        this.conexaoServico.getRemoteUsers('Pegando os usuários').subscribe((data) => { 
           this.users = data;
           console.log(this.users);
        });
    }