2017-08-12 35 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