Reputation: 139
I am storing if a checkbox is checked or not using AsyncStorage. When I reload the app, I see from logs that inside the asynchronous variable the correct information is stored. But, it is loaded after componentWillMount. Because of that, the checkbox does not appear checked, as it should be.
I think a good workaround will be to change the checkbox properties inside the asynchronous function. Do you think that would be a good solution? Do you have other suggestions for showing the correct checkbox value?
My code:
constructor(props) {
super(props)
this.state = {isChecked: false}
this.switchStatus = this.switchStatus.bind(this)
}
async getCache(key) {
try {
const status = await AsyncStorage.getItem(key);
if (status == null)
status = false
console.log("my async status is " + status)
return status
} catch(error) {
console.log("error", e)
}
}
componentWillMount(){
// key string depends on the object selected to be checked
const key = "status_" + this.props.data.id.toString()
this.getCache = this.getCache.bind(this)
this.setState({isChecked: (this.getCache(key) == 'true')})
console.log("my state is" + this.state.isChecked)
}
switchStatus () {
const newStatus = this.state.isChecked == false ? true : false
AsyncStorage.setItem("status_" + this.props.data.id.toString(), newStatus.toString());
console.log("hi my status is " + newStatus)
this.setState({isChecked: newStatus})
}
render({ data, onPress} = this.props) {
const {id, title, checked} = data
return (
<ListItem button onPress={onPress}>
<CheckBox
style={{padding: 1}}
onPress={(this.switchStatus}
checked={this.state.isChecked}
/>
<Body>
<Text>{title}</Text>
</Body>
<Right>
<Icon name="arrow-forward" />
</Right>
</ListItem>
)
}
There is no difference if I put everything in componentWillMount in the constructor.
Upvotes: 0
Views: 1873
Reputation: 139
Thank you for your answers. I am pretty sure await will work too, but I solved the problem before getting an answer. What I did was set the state to false in the beginning, and then update it in getCache. This way, it will always be set after getting the information from the local phone storage.
async getCache(key) {
try {
let status = await AsyncStorage.getItem(key);
if (status == null) {
status = false
}
this.setState({ isChecked: (status == 'true') })
} catch(e) {
console.log("error", e);
}
}
Upvotes: 1
Reputation: 8542
The return value of an async function is a Promise object. So you have to use then
to access the resolved value of getCache. Change your code to the following and it should work.
componentWillMount(){
// key string depends on the object selected to be checked
const key = "status_" + this.props.data.id.toString();
this.getCache(key).then(status => {
this.setState({ isChecked: status === true });
})
}
Upvotes: 0
Reputation: 1247
you make use of the async - await, but you are not waiting for your method in componentWillMount(). Try this:
componentWillMount(){
// key string depends on the object selected to be checked
const key = "status_" + this.props.data.id.toString()
this.getCache = await this.getCache.bind(this) // <-- Missed await
this.setState({isChecked: (this.getCache(key) == 'true')})
console.log("my state is" + this.state.isChecked)
}
Upvotes: 0