2

null zurück Ich stehe mit Ionic Storage vor einem sehr seltsamen Problem. Ich habe eine Methode, die einen Wert aus dem Speicher liest und gibt ein Versprechen ein Objekt enthält, das dem entspricht:Ionischer Speicher "Get" gibt nur bei dem zweiten Aufruf in Methode

private getAuthorizedOptions(): Promise<RequestOptions> 
    { 
     return this._storage.get('bdAccessToken') 
      .then(v => { 
       console.log("access token: ", v); 
       let token = v; 
       let header = new Headers({ 
        'Authorization': 'Bearer ' + token 
       }); 
       let ro = new RequestOptions({ 
        headers: header 
       }); 
       let options = new RequestOptions(); 
       if (options.headers) options.headers.delete("Authorization"); 
       options.headers = header; 
       return options; 
      }); 
    } 

Jetzt habe ich eine andere Methode, die dieses obige Verfahren rufen zweimal innerhalb einer Kette von Aktionen:

get(url:string, options?:RequestOptions): Observable<Response> 
    { 
     return Observable.fromPromise(this.getAuthorizedOptions()) 
       .mergeMap((options) => 
       { 
        return super.get(url, options) 
         .catch(err => { 
          if (err && err.status === 401) 
          { 
           return this._authService.refreshToken() 
            .mergeMap(r => 
             { 
              return Observable.fromPromise(this.getAuthorizedOptions()) 
               .mergeMap(opt => { 
                return super.get(url, opt) 
              }); 

             } 
            ) 
            .catch(err2 => { 
             console.log("redirecting."); 
             this.redirect(); 
             return Observable.throw(err2); 
            }); 
          } 
          else { 
           return Observable.throw(err); 
          } 
         }); 
       }); 
    } 

Jetzt verfolgt diese Methoden etwas seltsames. Wenn die Methode "getAuthorizedOptions()" das erste Mal aufgerufen wird, kann sie den Wert "bdAccessToken" aus dem Speicher sehr gut lesen. Beim zweiten Aufruf ist der zurückgegebene Wert NULL.

Ich habe meine Haare für zwei Tage auf diese ziehen, jede Hilfe wird geschätzt, wie Sie noch nie zuvor geschätzt worden! lol!

Antwort

2

Ich hatte einige Probleme mit dem Speicher und schrulligen Verhalten, die endete im Zusammenhang mit asynchronen Problemen.

Dinge, die nicht in der gewünschten/erwarteten Reihenfolge ausgeführt werden.

Also endete ich damit, meinen Dienst statusbehaftet zu machen und stattdessen auf ein BehaviourSubject-Ereignis zu überwachen.

import { Injectable }  from '@angular/core'; 
import { Storage }   from '@ionic/storage'; 
import { Server }   from './../model/server'; 
import { Subscription }  from 'rxjs/Subscription'; 
import { BehaviorSubject } from "rxjs/BehaviorSubject"; 

export class LoginService { 
    private static readonly SERVER = 'server'; 
    private servers$:BehaviorSubject<Server[]>; 
    private servers: Server[]; 
    public serversSubs:Subscription 

    constructor(public storage: Storage) { 

    this.servers$ = new BehaviorSubject([] as Server[]); 
    this.nextServersFromGetLocal(); // May need to be after subscribe.. Hot off presses.. 
    this.serversSubs = this.servers$.subscribe((servers:Server[]) => 
     this.servers = servers); 
    } 


    private nextServersFromGetLocal():void { 
    this.storage.get(LoginService.SERVER). 
     then((value:string) => { 
      this.servers$.next(JSON.parse(value) as Server[]); 
           } 
    ).catch(()   => { 
      this.servers$.next([] as Server[]); 
           } 
    ); 
    }  

    private nextServersFromSetLocal(servers:Server[]): void { 
    let data = JSON.stringify(servers); 
    this.storage.set(LoginService.SERVER, data); 
    this.servers$.next(servers); 
    } 

    getServers$(): BehaviorSubject<Server[]> { 
    return this.servers$; 
    } 

    addServer(addServer:Server): void { 
    // other code too... 
    this.servers.push(addServer); 
    this.nextServersFromSetLocal(this.servers); 
    } 

    changeServer(changeServer:Server): void { 
    // other code too... 
    this.nextServersFromSetLocal(this.servers); 
    } 

    deleteServer(deleteServer:Server): void { 
    // other code too.. 
    this.nextServersFromSetLocal(this.servers); 
    } 
} 

Dieses Refactoring hatte den zusätzlichen Vorteil, einen anderen Code zu vereinfachen, die auf den Dienst CRUD-Operationen haben, indem sie nicht wegen asynchrones Verhalten komplex verschachtelte/Wiederholung Versprechen/then/catch Codeblöcke inline mit. Hoffe das hilft dir.

Sie können eine Art der Vorstellung davon, wie diese App im Rahmen meiner Ionic arbeitete here, wie ich eine ähnliche Frage gestellt, und Sie können die HTML-Ansicht Seite dieser im Screenshot

+0

Dank sehen kann hilfst du mir vielleicht, einen Interceptor zu schreiben (der ein Access-Token aktualisieren kann), indem ich ionischen Speicher verwende? Ich habe die gleiche Sache vollständig mit localStorage entwickelt und funktioniert, aber ich bin stecken in die Arbeit mit einem asynchronen Speicher. –

+0

@behroozdalvandi - Ich wollte mehr in Interceptors innerhalb des Angular-Stacks suchen, bin aber noch dazu gekommen. Ich weiß, Angular University hat eine PDF, die Interzeptoren abdeckt. – JGFMK

Verwandte Themen