Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 离子储存“;获得;仅在方法内的第二次调用时返回null_Angular_Ionic Framework_Storage_Observable_Angular Promise - Fatal编程技术网

Angular 离子储存“;获得;仅在方法内的第二次调用时返回null

Angular 离子储存“;获得;仅在方法内的第二次调用时返回null,angular,ionic-framework,storage,observable,angular-promise,Angular,Ionic Framework,Storage,Observable,Angular Promise,我在离子存储方面面临着一个非常奇怪的问题。我有一个方法,它从存储器中读取一个值,并返回一个包含与之对应的对象的承诺: private getAuthorizedOptions(): Promise<RequestOptions> { return this._storage.get('bdAccessToken') .then(v => { console.log("access token: ", v

我在离子存储方面面临着一个非常奇怪的问题。我有一个方法,它从存储器中读取一个值,并返回一个包含与之对应的对象的承诺:

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;
            });
  }
private GetAuthorizationDoptions():承诺
{
返回此。_storage.get('bdAccessToken')
.然后(v=>{
日志(“访问令牌:”,v);
让token=v;
let header=新的头({
“授权”:“持票人”+代币
});
让ro=新的请求选项({
标题:标题
});
let options=new RequestOptions();
if(options.headers)options.headers.delete(“授权”);
options.headers=标题;
返回选项;
});
}
现在我有了另一个方法,它将在一系列操作中调用上述方法两次:

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);
                            }
                        });
                });
    }
get(url:string,options?:RequestOptions):可观察
{   
返回Observable.fromPromise(this.getAuthorizationDoptions())
.mergeMap((选项)=>
{
返回super.get(url、选项)
.catch(错误=>{
if(err&&err.status==401)
{
返回此。\u authService.refreshToken()
.mergeMap(r=>
{
返回Observable.fromPromise(this.getAuthorizationDoptions())
.mergeMap(opt=>{
返回super.get(url,opt)
});
}
)
.catch(err2=>{
日志(“重定向”);
这个。重定向();
返回可观察。抛出(err2);
});
}
否则{
返回可观察。抛出(错误);
}
});
});
}
现在追踪这些方法显示了一些奇怪的东西。第一次调用“getAuthorizationDoptions()”方法时,它可以很好地从存储器中读取“bdAccessToken”值。第二次调用时,返回的值为NULL


这件事我已经忙了两天了,任何帮助都会像你以前从未被感激过一样被感激!哈哈

我遇到了一些存储问题和奇怪的行为,最终与异步问题有关

未按所需/预期顺序执行的内容

因此,我最终使我的服务有状态,并监视一个行为主题事件

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);
  }
}
从'@angular/core'导入{Injectable};
从'@ionic/Storage'导入{Storage};
从“/../model/Server”导入{Server};
从'rxjs/Subscription'导入{Subscription};
从“rxjs/BehaviorSubject”导入{BehaviorSubject};
导出类登录服务{
私有静态只读服务器='SERVER';
专用服务器$:行为主体;
专用服务器:服务器[];
公用服务器SSUBS:订阅
构造函数(公共存储:存储){
this.servers$=newbehaviorsubject([]作为服务器[]);
this.nextServersFromGetLocal();//可能需要在subscribe.热关闭按钮之后。。
this.serversSubs=this.servers$.subscribe((服务器:Server[])=>
这是一个示例(服务器=服务器);
}
private nextServersFromGetLocal():void{
this.storage.get(LoginService.SERVER)。
然后((值:字符串)=>{
this.servers$.next(JSON.parse(value)作为服务器[]);
}
).catch(()=>{
此.servers$.next([]作为服务器[]);
}
);
}     
private nextServersFromSetLocal(服务器:服务器[]):无效{
让data=JSON.stringify(服务器);
this.storage.set(LoginService.SERVER,data);
this.servers$.next(服务器);
}
getServers$():行为主体{
返回此。服务器$;
}
addServer(addServer:Server):无效{
//还有其他代码。。。
this.servers.push(addServer);
this.nextServersFromSetLocal(this.servers);
}
changeServer(changeServer:Server):无效{
//还有其他代码。。。
this.nextServersFromSetLocal(this.servers);
}
deleteServer(deleteServer:Server):无效{
//还有其他代码。。
this.nextServersFromSetLocal(this.servers);
}
}
这种重构的另一个好处是简化了对服务执行CRUD操作的其他代码,因为异步行为不必内联复杂的嵌套/重复承诺/然后/捕获代码块。希望这对你有帮助


你可以在我的Ionic应用程序的上下文中了解它是如何工作的,因为我发布了一个相关的问题,你可以在屏幕截图中看到它的HTML视图一面

谢谢,你能帮我用Ionic存储编写一个拦截器(能够刷新访问令牌)吗?我已经使用localStorage完全开发并运行了同样的东西,但我一直致力于让它与异步存储一起工作。@behroozdalvandi-我一直想更多地研究Angular stack中的拦截器,但还没有着手解决它。我知道Angular大学有一个关于拦截器的PDF文件。