Search code examples
async-awaitreact-nativeasyncstorage

Unable to store values in asyncStorage in React Native


The value set in asyncstorage is null and also the log for usertext is { [TypeError: undefined is not an object (evaluating 'this.state.usertext')] line: 30, column: 34 }

what might be the problem here?

'use strict'
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Navigator,
Text,
TextInput,
Button,
AsyncStorage,
View
} from 'react-native';
import { Actions } from 'react-native-router-flux';
import api from './utilities/api';

export default class LoginScreen extends Component{

constructor(props) {
super(props);
this.state = { usertext: 'placeholder' , passwordtext: 'placeholder' ,buttonvalue: ' 
 Login'};
}

async login() {
const res = await api.getLoginResult();
const status= res.status;
console.log('log'+status);

if(status==='success'){
  try {
    console.log('usertext'+this.state.usertext);
    await AsyncStorage.setItem('username', this.state.usertext);
    var username = await AsyncStorage.getItem('username');
    console.log('username'+username);
    await AsyncStorage.setItem('password', this.state.passwordtext);
    } catch (error) {
    // Error saving data
   console.log(error);
    }
  Actions.HomeScreen();
}

}


render() {

return (
    <View style={styles.container}>
      <View style={styles.containerLogin}>
      <View style={styles.headerContainer}>
    <Text style={styles.welcome}>PLEASE LOGIN</Text>
    </View>
    <View style={styles.inputlayouts}>
    <TextInput 

      onChangeText={(usertext) => this.setState({usertext})}
      value={this.state.usertext}
    />

    <TextInput
      onChangeText={(passwordtext) => this.setState({passwordtext})}
      value={this.state.passwordtext}
    />
    </View>
    <View style={styles.buttonView}>
    <Button
      style={styles.buttonstyle}
      onPress={this.login}
      title={this.state.buttonvalue}
      color="#FF7323">
    </Button>
    </View>
    </View>
    </View>

   )


   }


   }


var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
backgroundColor: '#1AB591',
},
headerContainer:{
backgroundColor:'#FF7323'
},
buttonView:{
marginLeft:15,
marginRight:15,
marginBottom:15
},
inputlayouts:{
marginLeft:6,
marginRight:6,
marginBottom:10,
},
containerLogin: {
justifyContent: 'center',
alignItems: 'stretch',
backgroundColor: '#FFF',
marginLeft:20,
marginRight:20
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
color:'#FFF'
},
buttonstyle: {
width:20,
}
});

Solution

  • Change

    <Button
      style={styles.buttonstyle}
      onPress={this.login}
      title={this.state.buttonvalue}
      color="#FF7323">
    </Button>
    

    to

    <Button
      style={styles.buttonstyle}
      onPress={this.login.bind(this)}
      title={this.state.buttonvalue}
      color="#FF7323">
    </Button>
    

    When you do onPress={this.login}, the method reference to this will be different than your component. Binding this to method, allows you to reference your this in the function.