хранилище.get не работает в ионном хранилище (угловой)

#angular #typescript #ionic-framework #ionic-storage

Вопрос:

Я пытаюсь использовать ионное хранилище для сохранения и загрузки маркера аутентификации, который я использую для доступа к внутреннему API в своем приложении, но у меня возникли проблемы с получением значения из хранилища.

Я установил ионное хранилище (угловая версия), как указано на странице компонента GH: https://github.com/ionic-team/ionic-storage, используя приведенную ниже команду:

 npm install @ionic/storage-angular
 

Затем я импортировал службу хранения в свою глобальную службу, которую я создал, чтобы она была центром для всех глобальных значений в моем приложении:

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

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

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

    (...)
 

Затем я создал метод saveToken, который будет хранить маркер аутентификации, уже определенный _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:

введите описание изображения здесь

Но тут возникает проблема. Когда я пытаюсь загрузить сохраненный токен, используя метод, описанный ниже, я получаю возвращенное значение null, как если бы токен не был сохранен. Я делаю это, когда приложение снова открывается, чтобы восстановить сеанс входа в систему.

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

Приведенный выше код приведет к появлению следующих сообщений, указывающих на то, что значение не было возвращено из хранилища.

введите описание изображения здесь

Я запускаю приложение в браузере Chrome, использую ionic serve и подумал , что хранилище может быть сброшено после перезагрузки приложения, но я проверил вкладку «Приложение», и там есть маркер аутентификации.

Ответ №1:

Прежде чем я поделюсь возможным решением, а затем объясню:

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

Это один из способов использования обратного вызова для получения результата без изменения вашей внутренней логики.

Причина, по которой вы ничего не получаете, заключается в том, что вы пытаетесь вернуть асинхронный результат (обещание), а затем(); он всегда будет возвращать вам значение null. Ваш результат находится внутри «тогда».

Другой способ был бы таким (но вам придется перенести логику внутрь, откуда вы ее потребляете):

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

С уважением.

Комментарии:

1. Но в моем случае loadToken уже вернул обещание. Вопрос в том, что событие внутри then from storage.get возвращало значение null. Но я обнаружил проблему. На самом деле это было довольно глупо. Было еще одно хранилище.create, которое я забыл в другом классе, поэтому он дважды вызывал функцию create. Должен ли я удалить этот вопрос или оставить его здесь на случай, если у кого-то возникнет такая же проблема?

2. Ваш метод loadToken() не возвращает обещание, потому что вы указываете тип возвращаемого значения: «Обещание», вы возвращаете значение null, потому что тогда(). это метод, который ничего не возвращает. Затем() должен выполнить обещание, и если это произойдет, внутри него будет обратный вызов, который уведомит о возврате результата или в catch().

3. Я бы рекомендовал вам сначала понять, как работает обещание и как его использовать в машинописном тексте. Обещания должны быть выполнены и ждать результатов, а не возвращать метод, который их выполняет.