2017-08-12 21 views
2

內,離子存儲「get」僅在第二次調用時返回null我面臨着Ionic Storage非常奇怪的問題。我有讀取來自存儲一個值和一個返回一個包含對應於該對象的承諾的方法:在方法

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; 
      }); 
    } 

現在我有另一種方法,其中將動作的鏈內兩次調用此上述方法:

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); 
          } 
         }); 
       }); 
    } 

現在追蹤這些方法顯示了一些奇怪的東西。第一次調用「getAuthorizedOptions()」方法時,它可以很好地從存儲中讀取「bdAccessToken」值。第二次調用時,返回值爲NULL。

我一直在這拉我的頭髮兩天,任何幫助讚賞,就像你以前從未讚賞!大聲笑!

回答

2

我有一些存儲問題和古怪的行爲,最終導致與異步問題相關。

沒有按期望/預期順序執行的事情。

因此,我最終使服務有狀態並監視了BehaviourSubject事件。

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); 
    } 
} 

這重構了簡化,關於服務做CRUD操作等代碼,不必內嵌複雜的嵌套/重複的承諾/然後/捕獲的代碼,因爲異步行爲塊的額外好處。希望這可以幫助你。

可排序的瞭解其工作我的離子應用here的範圍內,因爲我發佈一個相關的問題,你可以看到這個HTML視圖側的截圖

+0

感謝的想法,可以你有什麼機會幫助我使用離子存儲編寫攔截器(能夠刷新訪問令牌)? 我有完全開發和使用localStorage功能相同的東西,但我堅持使它與異步存儲工作。 –

+0

@behroozdalvandi - 我一直有意在Angular堆棧中查看更多的攔截器,但還沒有解決它。我知道Angular University有一個涵蓋攔截器的PDF。 – JGFMK