AsyncStorage.removeItem is not removing the item - react-native

There are so many questions available and I have tried almost about 12 different ways but none are working. The most efficient one is:
async function removeItemValue(key) {
try {
await AsyncStorage.removeItem(key);
return true;
}
catch (exception) {
return false;
}
}
Then I'm calling it as:
useEffect(() => {
removeItemValue('#cartInfo');
}, []);
I've tried putting it outside of useEffect hook but still no effect. What am I doing wrong?
UPDATE:
Tried this as well but didn't work:
useEffect(() => {
removeItemValue('#cartInfo').then(() => { console.log('removed') })
}, []);
Also tried
useEffect(() => {
AsyncStorage.removeItem('#cartInfo', () => {
AsyncStorage.getItem('#cartInfo').then((res) => {
console.log("RES IS: " + res);
})
})
}, []);
Still no luck. I'm using v1.12.1 of #react-native-community/async-storage

As we discussed in chat, AsyncStorage.removeItem was actually working, and the issue is that setItem was being called too often, so that the value was replaced before being read later in getItem.

Related

why useState doesn't work with useEffect()?

const [dataSortArray, setDataSortArray] = useState([]);
// seeAllFeeds
const { data, loading, refetch, fetchMore } = useQuery(SEE_ALL_FEEDS_QUERY, {
variables: {
offset: 0,
},
});
useEffect(() => {
if (!loading) {
refetch();
console.log(data);
setDataSortArray(data);
console.log("✅", dataSortArray);
}
}, []);
as you can see I use useQuery.
if loading is done, i refetch the query and console.log(data) then data contains some array.
and I put this array into dataSortArray using setDataSortArray.
but when I console.log dataSortArray, it's empty.
✅ Array []
do you know why?
put loading into dependency array it will invoke every time value of loading is change passing Empty array [] as dependency array means it will render only once
useEffect(() => {
if (!loading) {
refetch();
console.log(data);
setDataSortArray(data);
console.log("✅", dataSortArray);
}
}, [loading]);
As #Dominic have pointed out in the question's comments (with a relevant link to another SO thread), useState is not effective immediately. So if you call setState on varA and console.log immediately afterwards, the varA won't be in the latest state you would expect.
I would suggest handling the state of dataSortArray in a separate useEffect.
useEffect(() => {
if (!loading) {
refetch();
console.log(data);
setDataSortArray(data);
}
}, []);
// Log dataSortArray when processing for setDataSortArray is completed by React.
useEffect(() => {
console.log(dataSortArray)
}, [dataSortArray]}

Why AsyncStorage getItem is returning null?

export const USER_KEY = "isLoggedIn";
export const phoneVerified = () => AsyncStorage.setItem(USER_KEY, 1);
export const userInfoVerified = () => AsyncStorage.setItem(USER_KEY, 2);
I have used the above functions to store the value and the below one to get the value.
export const isSignedIn = () => {
return new Promise((resolve, reject) => {
AsyncStorage.getItem(USER_KEY)
.then(res => {
console.log("from isSignedIn : "+res); //res is showing null.
if (res !== null) {
resolve(res);
} else {
resolve(0);
}
})
.catch(err => reject(err));
});
};
Why this always returns null? I was trying async/await but still getting null. I think somehow the data is not storing.
I'm afraid you can only store strings. Please refer to this React Native AsyncStorage storing values other than strings and this https://facebook.github.io/react-native/docs/asyncstorage.html#setitem
Thanks.
As answered by #Vishu Bhardwaj AsyncStorage accepts only string. So you can use JSON.stringify() and JSON.parse() in such cases.
I was stuck with this stupid problem for almost one week, no other way that is suggested in all communities worked for me, but then I found something that is built of react-native which its setState() callback function: https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296.
so the only way that I guarantee that it's the only secure way so far is this that u use the setState() function in your promise and everything that you need to run, put them on a function and call it for the setState() callback function , this is only way you can make sure yourself that you neither get null nor never calling the function . Here I'm going to provide an example of it which this.tokeToServer() is my function which it's used as a callback function.
try {
AsyncStorage.getItem('firebase_token',(err,item) => {
if (item) {
this.setState({
firebase_token: item,
}),this.tokenToServer();
}
});
} catch (error) {
console.log("Error retrieving data" + error);
}
As presented by friend Abdu4, I had the same problem for 4 days and searching for different sites and forums. Attempts with async/await and others, even though you should use these options, the one you completed and really worked was to assign the value through setState by callback
try {
AsyncStorage.getItem('TOKEN_KEY',(err,item) => {
if (item) {
setToken({
Token: item,
});
}
});
} catch (error) {
console.log("Error retrieving data" + error);
}

How to remove an item from AsyncStorage in react-native

How to remove an item from AsyncStorage? right now I am trying this code:
AsyncStorage.removeItem('userId');
but this is not working for me.
Try this:
async removeItemValue(key) {
try {
await AsyncStorage.removeItem(key);
return true;
}
catch(exception) {
return false;
}
}
This is what I did, had a similar issue.It works well when you want to remove an item based on its id. make sure each item has a unique id.
remove_user = async(userid) => {
try{
let usersJSON= await AsyncStorage.getItem('users');
let usersArray = JSON.parse(usersJSON);
alteredUsers = usersArray.filter(function(e){
return e.id !== userid.id
})
AsyncStorage.setItem('users', JSON.stringify(alteredUsers));
this.setState({
users:alteredUsers
})
}
catch(error){
console.log(error)
}
};
This looks correct, but maybe you are trying to read back from AsyncStorage too soon? It's asynchronous, so the change isn't applied right away and you might still see the key if you try to get it on the following line. Try to call AsyncStorage.removeItem with await or do what you want to do in the callback.
this delete method which removes object from array by passing index (here i called id)
async deleteData(id) {
try {
this.state.item.splice(id, 1);
await AsyncStorage.setItem("mylist",JSON.stringify(this.state.item))
this.setState({ item: JSON.parse(await AsyncStorage.getItem("mylist")) })
} catch (error) {
console.log(error);
}
};
and call this by using onPress method, here i am using button and pass index
<Button onPress={this.deleteData.bind(this,index)}>delete</Button>
This is the framework code for AsyncStorage.removeItem:
removeItem: function(
key: string,
callback?: ?(error: ?Error) => void
): Promise {
return new Promise((resolve, reject) => {
RCTAsyncStorage.multiRemove([key], function(errors) {
var errs = convertErrors(errors);
callback && callback(errs && errs[0]);
if (errs) {
reject(errs[0]);
} else {
resolve(null);
}
});
});
}
As you can see above it requires the key(Which is name of the item you set in asyncstorage that you want to delete) and a callback function. Make sure you have the correct key and the correct params and it should work fine.
Use removeItem() method to remove values from AsyncStorage in react.
try {
await AsyncStorage.removeItem(key);
console.log('Data removed')
}
catch(exception) {
console.log(exception)
}
try this for react-native
const deletCar = async () => {
try {
await AsyncStorage.removeItem('#storage_Key').then(() => {
// props.navigation.navigate('same page name refresh ');
/* setprevCar({ carNumner: '', carModel: '' }) return empty obj if deleted. */
})
}
catch (exception) {
return false;
}
}
if you want to remove the selected list :-
let key =[
'visitorId',
'visitorMobile',
'visitorData',
]
await AsyncStorage.multiRemove(key)

How Can I pass params with an API client to vue-head?

I am passing params from my API to vue-head but every time I do that it send me undefined in the head this is the code:
export default {
data: () => ({
errors: [],
programs: [],
}),
methods: {
getProgram() {
this.api.http.get(`videos/program/${this.programSlug}`)
.then(response => {
this.programs = response.data
})
.catch(error => {
this.errors = error
});
}
},
head: {
title: function() {
return {
inner: this.programs.name,
separator: '|',
complement: 'Canal 10'
};
}
}
}
any idea what I am doing wrong with my code??
First verify you are fetching the information correctly. Use console log and go to network tab and verify you are fetching the data correct, you might have to comment out vue-head. But what I think is that the problem might be due to vue-head rendering before the api call finishes then no data is being passed.
If you are using vue-router this can be easily solved with beforeRouteEnter() hook. But if not! apparently vue-head has an event that you can emit to update the component after render.
I haven't tried this but it should work. you can add the function below to your methods and call it after the promise is resolved i.e in the then closure.
methods: {
getProgram() {
this.api.http.get(`videos/program/${this.programSlug}`)
.then(response => {
this.programs = response.data
this.$emit('updateHead')
})
.catch(error => {
this.errors = error
});
}
}

VueRouter - Fetching Before Navigation - Multiple AJAX

I would like to use the beforeRouteEnter guard so I can be sure my data is loaded before going to a page. I read the example you can find here in the vue-router documentation.
Current situation
I'm more or executing two AJAX calls to get some data in the created lifecycle event.
export default {
created() {
const _this = this;
axios.get('/getCompanyDetails').then((response) => {
_this.private.company_details = response.data
});
axios.get('/getusers').then((response) => {
if(response.data){
_this.private.company_users = response.data;
}
});
}
}
What I try
beforeRouteEnter (to, from, next) {
function getCompanyDetails() {
return axios.get('/getCompanyDetails')
}
function getUsers() {
return axios.get('/getusers');
}
axios.all([getCompanyDetails(), getUsers()])
.then(axios.spread(function (company_details, company_users) {
next(vm => vm.setData(err, company_details, company_users))
}));
},
Am I on the right track ? The only thing I see here is I fell I'm required to call only one function setData in the next with all the parameters received from the different AJAX calls.
Is there a way to call several functions like setUsers(), setDetails() in the next ?
Is there a better way than what I'm doing ?
As #thanksd stated :
next((vm) => { vm.setUser(err, company_users); vm.setDetails(err, company_details); })
The final answer is then
beforeRouteEnter (to, from, next) {
function getCompanyDetails() {
return axios.get('/getCompanyDetails')
}
function getUsers() {
return axios.get('/getusers');
}
axios.all([getCompanyDetails(), getUsers()])
.then(axios.spread(function (company_details, company_users) {
next((vm) => { vm.setUser(err, company_users); vm.setDetails(err, company_details); })
}));
},