2

Below is my code for saving and getting my JWT token using Redux Thunk.But it Always give my null.Where i am Wrong?

In profile.js file I want to get My Saved Token.But it always gives me null. Is there any problem in AsyncStorage.setItem and getItem method?

Thank You in Advance :)

authAction.js

 import {PostData} from '../../components/API';
import {GET_TOKEN,SAVE_TOKEN} from '../type';
import {saveUserToken} from '../../utils/asyncStorage'

export const authenticate = (request)  => {
        PostData("login",request,'POST')
        .then(response =>{
            if(response.error){
                console.log("Please try again later");
              }else{
                if(response.meta.status=="ok"){
               console.log("SUCCESS : " +response.meta.message);
               saveUserToken(response.data.user.token);
               dispatch({type: SAVE_TOKEN,payload:response.data.user.token})
              }else{
                console.log("MESSAGE : " +response.meta.message);
              }
        }
        }).catch(error => {
          console.log("ERROR : " +error);
      })
}

authReducer.js

   import  {GET_TOKEN,SAVE_TOKEN} from '../type';

   const initialState = {
    token : null,
   };

  export default (state = initialState, action) =>{
    switch(action.type){
        case GET_TOKEN:
            return { ...state, token: action.token };
        case SAVE_TOKEN:
            return {...state,token:action.token} ;
        default :
            return state;
    }
  };

asyncStorage.js

 import { AsyncStorage } from 'react-native';
 import {GET_TOKEN,SAVE_TOKEN} from '../redux/type';

    export const saveToken = token => ({
        type: SAVE_TOKEN,
        token
    });
    export const getUserToken = () => {
        return AsyncStorage.getItem('userToken')
            .then((data) => {
                console.log("GET TOKEN : " +data);
                // dispatch({type: GET_TOKEN,payload:data})
            })
    }

    export const saveUserToken = (response) => {
          AsyncStorage.setItem('userToken',JSON.stringify(response))
            .then((data) => {
                alert("SAVE TOKEN = " + JSON.stringify(response)); 
            })
    }

profile.js

    import React, { Component } from 'react';
import {StyleSheet,View,Text} from 'react-native';
import { connect } from 'react-redux';
import { getUserToken } from '../../utils/asyncStorage';

class profile extends Component {
    static navigationOptions = {
        header: null,
    };
    constructor() {
        super();
    }
    componentDidMount() {
        getUserToken()
        console.log("TOKEN=" +this.props.token.token)
    }
    _bootstrapAsync = () => {
    };
render() {
  return (
    <View style={ styles.container }>
       <Text onPress={this._bootstrapAsync()}>PROFILE </Text>

    </View>
    );
  }
}

const mapStateToProps = state => ({
    token: state.token,
});


const mapDispatchToProps = dispatch => ({
    getUserToken: () => dispatch(getUserToken()),
});

export default connect(mapStateToProps,mapDispatchToProps)(profile);
Chitra Nandpal
  • 413
  • 4
  • 24

3 Answers3

1

Use redux-persist to automatically sync part of your store: Duplicate of How and where to save the whole redux store using AsyncStorage

Markus
  • 1,598
  • 2
  • 13
  • 32
0

There was a silly mistake in my code. I was forgot to use async and await keyword in AsyncStorage that is the reason why it gets always null.

Thanks

Chitra Nandpal
  • 413
  • 4
  • 24
-1

It's probably better to use AsyncStorage to store the token on the device rather than in Redux.

import { AsyncStorage } from 'react-native';

const setToken = async (token) => {
    try {
        await AsyncStorage.setItem('MY_TOKEN', token);
    } catch(e) {
        console.error(e);
    }
}

const getToken = async () => {
    const token = await AsyncStorage.getItem('MY_TOKEN');
    return token;
}

EDIT: If you don't want to use async/await then you can just change the code in asyncStorage.js to be like the below:

export const getUserToken = () =>
    AsyncStorage.getItem('userToken');
}

And the code in profile.js to read:

class profile extends Component {
    ...
    componentDidMount() {
        getUserToken().then((token) => console.log("TOKEN=" + token));
    }
    ...
}
V. Dimitrov
  • 162
  • 1
  • 12
  • 1
    This will not get the benefits of redux, e.g. being able to use react-redux, ability to listen on state and request it synchronously. – Markus Mar 14 '19 at 06:58
  • 1
    @Markus There is absolutely no need to over-engineer something as simple as storing a JWT. The problem described in the initial question is that when `getUserToken` is called, it returns a Promise with an `undefined` value, because the promise hasn't resolved. Async/await will fix the issue without adding additional boilerplate for what is a simple process. – V. Dimitrov Mar 15 '19 at 12:34