Edgar Pisxid
Edgar Pisxid

Reputation: 79

Async REST API Request IONIC

I'm trying to save data into an IonicStorageModule from a request to my REST API, the data is user info like; Name, Phone, Address, etc.

Right now I have this:

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

@Injectable()
export class ServicioApiProvider {
  results:Object[];
  loading:boolean;

  constructor(public http: Http) {
    this.results = [];
    this.loading = false;

  }

  buscar(ruta) {
      let promise = new Promise((resolve, reject) => {
      this.http.get(ruta)
        .toPromise()
        .then(
            res => { // Success
            this.results = res.json();
            console.log(res.json());
            resolve();
            },
            msg => { // Error
            reject(msg);
            }
          );
      });

      console.log("Last line"); 
      return promise;
   }
}

But always the line: "console.log("Last line");" executes before the promise.

Any Ideas to save the response from the REST API to an IonicStorageModule?

Upvotes: 2

Views: 2919

Answers (1)

sebaferreras
sebaferreras

Reputation: 44659

Since the http.get method is async, if you want that line to be executed when the data is ready, place it inside of the then. You can also simplify your buscar(...) method like this:

buscar(ruta): Promise<any> {
    return this.http.get(ruta)
        .map(res => res.json())     // Get the body of the response
        .toPromise()                // Convert the observable into a promise
        .then(
            response => {           // Success callback

                this.results = response;
                console.log(response);

                // Since the http get is async, you need to place the logic
                // to save the data in the storage here!
                // ...
                // this.storage.set('data', JSON.stringify(response));
                // ...

                console.log("Last line"); 
            },
            error => {              // Error callback

                // TODO: Handle error
                // ...

                console.log(error);
                return error;
            });
}

EDIT

I'm calling this method from one page:this.servicioApi.buscar(this.path); After that I want to access to the data that I saved in storage, but it returns null (And the get to access to the storage variable executes before the call to the method "buscar"), and if I access to the data from another page it returns the JSON

Let me modify again the method, in order to return the response:

buscar(ruta): Promise<any> {
    return this.http.get(ruta)
        .map(res => res.json())     // Get the body of the response
        .toPromise()                // Convert the observable into a promise
        .then(
            response => {           // Success callback

                this.results = response;
                console.log(response);

                // Since the http get is async, you need to place the logic
                // to save the data in the storage here!
                // ...
                // this.storage.set('data', JSON.stringify(response));
                // ...

                console.log("Last line");

                // UPDATE: return the response
                return response;


            },
            error => {              // Error callback

                // TODO: Handle error
                // ...

                console.log(error);

                // UPDATE: return null if there was an error
                return null;
            });
}

So now we're returning the response (or null if there was an error). That gives us two ways of getting that data when calling that method:

1) Getting the response from the callback

this.servicioApi.buscar(this.path).then(res => {
    if(res) {
      // Here you can use the response
      // ...
    } else {
      // Here you can do something if there was an error
      // ...
    }
});

2) Getting the response from the storage

this.servicioApi.buscar(this.path).then(() => {
    this.storage.get('data').then(responseJson => {
      if(responseJson) {

        // Parse the response since it is a JSON
        let response = JSON.parse(responseJson);

        // Here you can use the response
        // ...
      }
    });
});

EDIT II

Just like @Sampath mentioned, you could just use observables (which is Angular recommended way), like this:

buscar(ruta): Observable<any> {
    return this.http.get(ruta)
        .map(res => res.json())     // Get the body of the response
        .map(response => {

                this.results = response;
                console.log(response);

                // Since the http get is async, you need to place the logic
                // to save the data in the storage here!
                // ...
                // this.storage.set('data', JSON.stringify(response));
                // ...

                return response;
            });
}

And then just subscribe to that method:

this.servicioApi.buscar(this.path)
    .subscribe(
        res => {
          // Here you can use the response
          // ...
        },
        error => {

            // TODO: Handle error
            // ...

            console.log(error);
        });

Upvotes: 4

Related Questions