4

I know the similar question has been asked such as this, but am not able to find an answer to this. I am a newbie to react-native as well. I need to retrieve data from storage this is how I store the value after API call

_storeData = async response => {
 it AsyncStorage.setItem(token, (response))
  .then(() => {
  this.setState({
     shouldLoad : false
   });  
    console.log("Data saved successfully" + response);
    this.props.navigation.navigate("HomeScreen");
  })
  .catch(() => {
    console.log("There was an error saving the data");
  });
 };

This is how I tried to retrieve data from AsyncStorage

 AsyncStorage.getItem(token).then((token) => {
  this.setState({
    token : tokentoken,
    currentState : false
  });
});

What am trying to achieve is session management. On login, I save the sessionToken to AsyncStorage, and when the app is started again, I need to retrieve the data back. I tried different code but am not getting output.

Any help will be appreciated Thanks in advance

EDIT 1.

Am pasting the whole code here so that anyone could point out where am going wrong.

export default class App extends Component {
 constructor() {
super();
this.state = {
  token: null,
  currentState : true,
};
}

 componentDidMount() {
AsyncStorage.getItem(token).then((token) => {
  this.setState({
    token : tokentoken,
    currentState : false
  });
});
  }


  render() {
var ggg = this.state.token;
console.log(ggg);

if(this.state.currentState === false){

if (this.state.token === "" || this.state.token === null) {
  return <LoginNav />;
} else {
  return <HomeNavigatorNew />;
}

}

 else{
return (  <ActivityIndicator  
  animating={true}
    style={{ 
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',

      height: 80
    }}
    size="large"
  />)
  }
  }
 }

EDIT 2.

I was writing the above code in App.js I just moved the whole code to Login.js(another file) and it just worked. Does that mean anything.. .? Is it like that I should write retreiving code in App.js

EDIT 3. Thanks to @Mohammed Ashfaq and @Samer Murad for responding so quickly. In Sammrs code I noticed the AsyncStorage is imported in curly parenthes not without them. I was importing without them. I had mentioned in my EDIT 2 that the code was working in another file in which the AsyncStorage is impoted in curly paranthes. Leaving the modified working code for future reference for someone

 import React, {Component} from "react";
 import   {AsyncStorage, ActivityIndicator} from "react-native";
 import { createStackNavigator} from "react-navigation";

 export default class App extends Component {
  constructor() {
   super();
   this.state = {
  token: null,
  currentState: true,
};
 }
  _retrieveData = async () => {
   console.log("Data retrieved successfully");

 // var tokenRetrieved = AsyncStorage.getItem('LoginTocken');
await AsyncStorage.getItem('LoginTocken')
  .then(value => { 
    return (value);
  })
  .then ( valueJson => {
    this.setState({
      token : valueJson,
      currentState : false
    });
    console.log("Data retrieved successfully", valueJson);
  })
  .catch((error) => {
    console.log("There was an error retrieving the data" + error);
  });



  };

  handleSession = async () => {
console.log("handleSession");
   this._retrieveData().catch((error) => {console.log("error is " + 
 error);});
  };

  componentWillMount() {
console.log("componentWillMount");
this.handleSession();
  }


  render() {


if (this.state.token === "" || this.state.token === null) {
  return <LoginNav / > ;
} else {
  return <HomeNavigatorNew / > ;
}
 }

}

I don't have a clue why and how it make difference when some import are done without curly parenthes**{}** where some are done with them. If anyone know why the curly paranthes are omitted/added at times I request them to leave a answer.

2 Answers 2

4

Here is a LocalStorage wrapper I wrote not so long ago, It also includes the functionality to set TTL on an object/key if you need an expiration date behavior, I use it for the same logic as you do, which is to check if there is a saved token and navigate to the main app view instead of the login page.

Here is the wrapper:

// RN < 0.59
import { AsyncStorage } from 'react-native'
// RN > 0.59
import AsyncStorage from '@react-native-community/async-storage';


/**
 *
 * @param key Key value of the object to be saved
 * @param object The Object to save
 * @param ttl (Optional) set an expiration date on an object in ms
 * @return {Promise<void>}
 */
export const setObjectForKey = async ({key, object, ttl = undefined }) => {

    if (!key) throw new Error('Cannot set an object without a key');

    if (!object) throw new Error('Cannot set a key without an object');

    let expiresAt = undefined;
    if (ttl) {
        expiresAt = new Date().getTime() + ttl;
    }
    let wrappedObj = {
        object,
        expiresAt,
    };
    let stringedWrapper = JSON.stringify(wrappedObj);

    return await AsyncStorage.setItem(key,stringedWrapper)
};


/**
 *
 * @param key The key of the object to remove
 * @return {Promise<void>}
 */
export const removeObjectForKey = async (key) => {
    return await AsyncStorage.removeItem(key)
};


/**
 *
 * @param key The key of the object to retrieve
 * @return {Promise<*>}
 */
export const getObjectForKey = async (key) => {
    let now = new Date().getTime();
    let stringedWrapper = await AsyncStorage.getItem(key);

    if (!stringedWrapper) throw new Error('No key found for object');

    let wrapper = JSON.parse(stringedWrapper);
    if (wrapper.expiresAt < now) {
        // Object expired
        AsyncStorage.removeItem(key);
        throw new Error('Object expired');
    } else {
        return wrapper.object;
    }
};

And here is a usage example (in my solution I have a redux middleware so after I retrieve an object I call dispatch):

GET:

let key = 'APP_TOKEN';
localstorage.getObjectForKey(key)
            .then((retrievedObject) => {
               // Do what you want with object
            })
            .catch((err) => {
               // Handle error, Object either doesn't exist, expired or a system error
            })

SET:

 let key = 'APP_TOKEN';
 let object = {token: 'JWT_HASH'};
 let ttl = undefinded // TTL is optional
 localstorage.setObjectForKey({
            key,
            object,
            ttl,
        })
            .then(() => {
               // Set was successfull
            })
            .catch((err) => {
                // Handle Error
            })

DELETE:

localstorage.removeObjectForKey(key)
            .then(() => {
              // Successfully deleted
            })
            .catch((err) => {
               // Object either doesn't exist to delete or system error
            })

Notice that I actually save objects that I stringify, so even if I'm save the api token, I actaully save an object with a token as a key, i.e: {token: 'TOKEN'}

Hope that helps

UPDATE 2019-06-06

As of react-native 0.59, the AsyncStorage module is deprecated due to the efforts to make react-native's core library thinner... the AsyncStorage should now be installed through @react-native-community/react-native-async-storage

Sign up to request clarification or add additional context in comments.

Comments

2

 /* Login Screen */

async storeSessionToken(token) {
  try {
    await AsyncStorage.setItem('token', token);
    console.log("Data saved successfully");
    // Rest of your code
  } catch (error) {
    console.log("Error while storing the token");
  }
}




/* Splash Screen  */ 

async retrieveSessionToken() {
  try {
    const token = await AsyncStorage.getItem('token');
    if (token !== null) {
      console.log("Session token",token );
      return token;
    }
   } catch (error) {
     console.log("Error while storing the token");
   }
}



// calling retrieveSessionToken
componentDidMount() {
  this.retrieveSessionToken()
  .then((token)=> { 
    if(token) this.setState({token: token})
  })
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.