Chris Yeung
Chris Yeung

Reputation: 11

React Native AsyncStorage returns promise even used await and async

I researched the problem in AsyncStorage.getItem. Many of comment said we should apply await and anync on AsyncStorage, such as

React Native AsyncStorage returns promise instead of value.

AsyncStorage.getItem returning promise

However, it still return Promise to me like the snapshot below. Inside this Promise, _55 contained correct user information. Would every people help me figure out the problem and give me possible solution? Thank You!

Snapshot: Debugger snapshot

Reducer:

import {AsyncStorage} from "react-native";
import {LOGIN, LOGOUT, UPDATE} from './../actions/authActions'
import user from "./index";

export type State = {
    user: Object,
    login: boolean,
}

getUser = async (string) => {  //Get user information form AsyncStorage
    try {
         return await AsyncStorage.getItem(string)
                  .then((user) => {
                     if (user !== null) {
                        return JSON.parse(user);
                     } else {
                        return null;
                   }
                });
    } catch (error) {
        return null;
    }
};

const initialState = {
    info: getUser(),
    login: !!this.info, // if not null, login = ture
};

function loginReducer(state: State = initialState, action) {
    switch (action.type) {
        case LOGIN:
            return {
                info: action.payload,
                login: true,
            };
        case LOGOUT:
            return {
                info: null,
                login: false,
            };
        case UPDATE:
            return {...state, info: Object.assign(state.info, action.payload)};
        default:
            return state;
    }
}   

Action:

import {AsyncStorage} from "react-native";
import {requestLogIn, requestLogOut} from "../../config/api/authApi"

export const LOGIN = "LOGIN";
export const LOGOUT = "LOGOUT";
export const UPDATE = "UPDATE";
export const ERROR = "ERROR";

export function login(user) {
    return dispatch => {
        return AsyncStorage.setItem("user", JSON.stringify(user)) //Store user information in AsyncStorage
            .then(() => {
                dispatch({
                    type: LOGIN,
                    payload: user
                })
            }).catch((error) => {
                console.warn("Error: ", error);
                dispatch({
                    type: ERROR,
                    payload: null
                })
            });
    }
}

export function logout(token) { //
    return dispatch => {
        return requestLogOut(token).then((status) => {
            if (status) {
                return AsyncStorage.removeItem("user")
                    .then(() => {
                        dispatch({
                            type: LOGOUT,
                        })
                    }).catch(() => {
                        dispatch({
                            type: ERROR,
                            payload: null
                        });
                    });
            } else {
                dispatch({
                    type: ERROR,
                    payload: null
                });
            }
        })

    }
} ..// other actions

Upvotes: 1

Views: 806

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074335

Your getUser is an async function, but you're not awaiting it:

const initialState = {
    info: getUser(),      // <=== here
    login: !!this.info,
};

async functions return promises.

Without getting into the broader context of the code too much, you probably want to do something like this:

const initialState = {
    info: null,
    login: !!this.info,
};
getUser().then(info => initialState.info = info);

Or something along those lines. Note that that means initialState.info will be null until the storage returns the value. If you have more initialization that needs that value, you'll have to trigger it from the then handler above.

(No catch on that because you've defined getUser such that it cannot reject.)

Upvotes: 1

Related Questions