promesas example angular cordova typescript ionic-framework ionic2

example - promise angular 6



Cómo implementar promesas dentro de Ionic/Cordova (2)

Estoy construyendo una aplicación Ionic que funciona usando autenticación basada en tokens. Cuando el usuario realiza la autenticación, se almacena un token de acceso en el almacenamiento local.

Mi código luego llama a un proveedor para cualquier información que necesita (en este caso, está extrayendo ''Programas de capacitación'' de una API).

A su vez, ese proveedor llama a otro proveedor que maneja las solicitudes HTTP para mi API. Establece efectivamente los encabezados necesarios e inicia la solicitud HTTP, luego devuelve la respuesta al proveedor solicitante.

Todo esto funciona bien, hasta que necesite obtener el token de acceso del almacenamiento antes de realizar la solicitud HTTP. Parece que el acceso a los datos del almacenamiento no es instantáneo, y en su lugar utiliza la sintaxis de then .

Parece que cuando llamo al proveedor desde mi código, éste pasa al proveedor de Programas de capacitación y luego al proveedor de API. El código aquí se ejecuta y vuelve a pasar, pero esto sucede antes de que mi aplicación tenga la oportunidad de obtener lo que necesito del almacenamiento.

Traté de colocar todo en la solicitud dentro de la llamada del método storage.get , pero eso no funcionó.

Aquí está mi código de solicitud:

this.trainingProgramme.get_programmes().subscribe((res) => { loader.dismiss(); console.log(res); });

Lo que se filtra a mi proveedor de programa de trainingProgramme :

get_programmes() { let seq = this.api.get(''training-programmes''); seq .map(res => res.json()) .subscribe(); return seq; }

Que a su vez pasa a mi proveedor de api :

export class Api { base_url: string = ''https://******.com''; url: string = this.base_url + ''/api/v1''; access_token: string; constructor( public http: Http, private storage: Storage) { // Grab access token and store it storage.get(''access_token'').then((val) => { console.log(''Pulled access token from local storage'', val); this.access_token = val; }); } // Performs a GET request with auth headers get(endpoint: string, params?: any) { let headers = new Headers(); headers.append(''Authorization'', ''Bearer '' + this.access_token); let options = new RequestOptions({ headers: headers }); return this.http.get(this.url + ''/'' + endpoint, options); } }

Esto no produce ningún error, pero los encabezados que se envían son:

Authorization: Bearer undefined

En resumen: creo que la llamada de storage está ocurriendo de forma asíncrona, por lo que la llamada HTTP se inicia antes de que tenga la oportunidad de obtener el token de acceso. ¿Cómo puedo evitar que esto suceda o esperar a que termine el storage antes de llamar a la solicitud HTTP? Simplemente colocando mi código adentro no funcionará, ya que este método ya está dentro de la subscribe , así que obtengo errores.

ACTUALIZACIÓN 1:

Debajo está el código que he usado colocando el código de storage dentro del método mismo, en lugar de en el constructor, y luego colocando todo el código, incluida la llamada HTTP, dentro del then .

// Performs a GET request with auth headers get(endpoint: string, params?: any) { // Grab access token and store it this.storage.get(''access_token'').then((val) => { console.log(''Pulled access token from local storage'', val); this.access_token = val; let headers = new Headers(); headers.append(''Authorization'', ''Bearer '' + this.access_token); let options = new RequestOptions({ headers: headers }); return this.http.get(this.url + ''/'' + endpoint, options); }); }

Los errores con:

Runtime Error Uncaught (in promise): TypeError: Cannot read property ''map'' of undefined TypeError: Cannot read property ''map'' of undefined at TrainingProgramme.get_programmes

Presumiblemente, esto se debe a que el método get no devuelve nada cuando se espera, ya que el retorno ahora es asincrónico.


En el lado del constructor de su proveedor de API está escribiendo su código para obtener los datos almacenados que es asíncrono, recuerde que JavaScript es sincrónico, así que una vez que se llama asincrónico me refiero a store.get().then() se completa la parte del constructor no es esperando a almacenar el valor de this.access_token y está llamando a la función get() .

Para decirle a storage.get async llamar que espere hasta que se complete y luego vaya y llame al método get() solo use la palabra clave async y await

constructor( public http: Http, private storage: Storage) { this.getAccessToken(); //only after completing this function it will go the next command } async getAccessToken(){ // Grab access token and store it //below i have writen await inorder to wait until this is completed. const token = await storage.get(''access_token'').then((val) => { console.log(''Pulled access token from local storage'', val); this.access_token = val; }); }

trata de colocar el código de arriba y verifica que te ayude


prueba esto :)

yourlongmethod() { return new Promise((resolve, reject) => { //your code var data = "Any data you want to return with the promise"; resolve(data); });

}

Entonces puedes llamar esto

yourlongmethod (). then ((res) => {

console.log (res)})