Ionic 存储.get是不再工作在离子存储(Angular )

kulphzqa  于 2023-03-06  发布在  Ionic
关注(0)|答案(2)|浏览(182)

我尝试使用离子存储来保存和加载一个身份验证令牌,该令牌用于访问我的APP中的后端API,但我无法从存储中获取值。
我已经安装了离子存储(Angular 版本),如组件GH页面所示:https://github.com/ionic-team/ionic-storage,使用以下命令:

npm install @ionic/storage-angular

然后,我将存储服务导入到我的Globals服务中,我创建该服务作为应用程序中所有全局值的中心:

import { Storage } from '@ionic/storage-angular';

@Injectable()
export class Globals {
    private _authenticationToken: string;

    constructor(private storage: Storage) {
        this._authenticationToken = null;
        this.storage.create();        
    }

    (...)

然后,我创建了一个saveToken方法,它将在ionic存储中存储身份验证令牌(已通过另一个方法在_authenticationToken中定义):

public saveToken() : Promise<void>
{
    console.log("Saving token");
    console.log(this._authenticationToken);
    return this.storage.set("AuthenticationToken", this._authenticationToken)
        .then(valor => console.log("token saved."));
}

当我执行saveToken方法时,结果如下(忽略红色的行,它们来自其他进程,因为saveToken是异步的):

所以我的令牌被保存,我可以在Chrome开发工具的应用程序选项卡中看到它的值:

但问题来了。**当我尝试加载保存的令牌时,使用下面的方法,我得到一个空值返回,好像令牌没有保存。**当应用程序再次打开时,我正在这样做,以恢复登录会话。

public loadToken() : Promise<void>
{
    return this.storage.get("AuthenticationToken")
        .then(v => {
            console.log("token loaded");
            console.log(v);
            this.setToken(v);
        });
}

上面的代码将产生以下消息,指示没有从存储返回值。

我正在chrome浏览器中运行应用程序,使用ionic serve,并认为存储可以在应用程序重新加载后重置,但我已经检查了应用程序选项卡和身份验证令牌在那里。

xuo3flqw

xuo3flqw1#

在我分享可能的解决方案并解释之前:

public loadToken(handler: (result?: any) => void) : void
{
    this.storage.get("AuthenticationToken")
        .then(v => {
            this.setToken(v);
            handler(v);
        });
}
...

this.loadToken((result?: any) => {
     // here your result
});

这是一种使用回调来获取结果而不移动内部逻辑的方法。
您没有得到任何结果的原因是因为您试图返回一个异步结果(promise)和**then();**它总是返回空值。你的结果在then里面。
另一种方法是这样的(但是你必须从你使用它的地方迁移里面的逻辑):

public loadToken() : Promise<any>
{
    return this.storage.get("AuthenticationToken");
}
...

const token = await loadToken(); // await is a syntactic sugar, it summarizes use of then(); on one line and you must wait for the result to return before continuing.
this.setToken(token);

最好的问候。

mjqavswn

mjqavswn2#

我遇到了同样的问题,并设法解决它这样:

import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage-angular';

@Injectable({
  providedIn: 'root'
})
export class StorageService {

  constructor(private _storage: Storage) {
    this._storage.create();
  }

  public async set(key: string, value: any) {
    await this._storage?.set(key, value);
  }

  public async get(key: string): Promise<any> {
    const data = await this._storage?.get(key);
    return data;
  }

  public async remove(key: string): Promise<void>{
    await this._storage?.remove(key);
  }

  public async clear(): Promise<void>{
    await this._storage?.clear();
  }
}

为了访问令牌,在我的示例中,我使用了一个保护:

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } 
from '@angular/router';
import { StorageService } from '../storage/storage.service';

@Injectable({
  providedIn: 'root'
})
export class GuardService implements CanActivate {

  constructor(private router: Router, private storage: StorageService) {}

  async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    const key = "user";
    const data = await this.storage.get(key);
    if (!data) {
      this.router.navigateByUrl('/login');
      return false;
    } else{
      this.router.navigateByUrl('/home');
      return true;
    }
  }
}

相关问题