AsyncStorage.setItem Promise not fulfilling or erroring? - javascript

I've looked through a few posts such as this post
I want to use a console.log to see if I successfully set an item to AsyncStorage.
Here is my code:
export function saveDeckTitleAPI(key,title) {
return AsyncStorage.setItem(uuid(), JSON.stringify(new DeckCreator(title)))
.then(data => {
debugger;
console.log('INSIDE SET ITEM');
AsyncStorage.getItem(data.key).then(item => {
console.log(item);
})
})
.catch(err => {
console.err(err);
});
}
When I run this code, the .then and the .catch aren't fulfilled. I tried logging the promise by itself, and I get a similar result as the post above.
Do I have to use async/await? Is that the problem here? Here are the docs to setItem.

You can pass a callback as the third argument. If there's an error, it will be the callback's first parameter. If there's no error, console log that all is well and good, otherwise log the error.

Yes you need async and await
You can get an inspiration from the code below, the way I do a facebook login with setItem
const doFacebookLogin = async dispatch => {
const { type, token } = await
Facebook.logInWithReadPermissionsAsync('xxxx', {
permissions: ['public_profile']
});
if (type === 'cancel') {
return dispatch({ type: FACEBOOK_LOGIN_FAIL });
}
await AsyncStorage.setItem('fb_token', token);
dispatch({ type: FACEBOOK_LOGIN_SUCCESS, payload: token });
};

Related

Return data from Promise and store it in variable after API Call

I´m pretty new to Promises and found many examples here how to access the actual value which is always done with console.log. But my goal is to store the result in a variable and work with it.
getdata = () =>
fetch(
"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&outputsize=full&apikey=demo"
)
.then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error("This is an error");
}
})
.then(data => {
console.log(data);
});
getdata();
This code works. Can you help me to rewrite it that the getdata() function allows me to store the result in a variable. Return does not work since I will receive another pending Promise.
You can do it like this:
getdata = () =>
fetch(
"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&outputsize=full&apikey=demo"
).then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error("This is an error");
}
});
getdata().then(data => {
//I can do whatever with data
});
Of course you would also want to handle the scenario where the request failed, so you could also chain a .catch(). Alternately, if you have your build process configured for it, you can use async and await so you could do:
try {
const data = await getdata();
} catch(err) {
}
This would need to be in a function marked as async
Well at first we need to declare a variable let's say temp. Then use fetch API to request our query with URL. If server status is 200 then it will return a promise, we need to use then method by passing any argument (res, response, r anything...) and then a fat arrow function (=>) so that we can make the response as json format. After then we need to use another then method to return the json output and assign the value to our declared temp variable.
But if there is any error like 500, 400, 404 server error we need to use catch method with err argument and console it out.
let temp;
fetch('https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&outputsize=full&apikey=demo')
.then(res => res.json())
.then(data => temp = data)
.catch(err => console.log(err));

How to retrieve axios data from the promise

I am currently trying to query my backend using axios and to that specific address I am sending with res.json an object and I am also able to see it with postaman. But when trying to build a function to retrieve it, my object looks like:Promise {pending}. How can i refactor my function ?
isAuthenticated = () => {
return axios.get('https://myaddress/authenticate')
.then(function (response) {
return response.data
})
};
You need to call the promise like so:
isAuthenticated().then(result => console.log(result))
.catch(error => console.log(error));
Use This code and let me know if still, you face a problem.
const isAuthenticated = () => {
return axios.get('https://myaddress/authenticate').then(response => {
// returning the data here allows the caller to get it through another .then(...)
return response.data
}).catch(error => console.log(error));
};
isAuthenticated().then(data => {
response.json({ message: 'Request received!', data })
})
here is similar questions as yours: Returning data from Axios API || Please check it as well.

What might happen if I call `AsyncStorage.setItem` without await in non async function?

I am using fetch method to get some data from the server. Once I get that data, I need to store some of it (access_token to be more precise cause I am using oauth) in AsyncStorage. I tried doing just AsyncStorage.setItem without await, not how it is shown in https://facebook.github.io/react-native/docs/asyncstorage, and it worked just fine.
I changed it to:
fetch ('site/login', POST ...)
.then((response) => response.json())
.then(async(responseJson) => {
if (user.valid)
await AsyncStorage.setItem('access_token', responseJson.token);
And it works fine too. But I have 2 questions now:
Is my implementation with fetch and async correct?
And what might happen if I don't use await/async in this case?
Sorry, I am kinda new to Promises and Asynchronous methods in Javascript. Thanks!
async/await is just syntactic sugar over Promises. You're already using Promises, so there's no need to do that. Just return the Promise:
fetch ('site/login', POST ...)
.then((response) => response.json())
.then((responseJson) => {
if (user.valid) { // not sure where 'user' came from, but whatever
return AsyncStorage.setItem('access_token', responseJson.token);
} else {
throw new Error('Invalid user');
}
})
.then(_ => { // storage set, don't care about return value
// do stuff
})
.catch((err) => {
// handle error, including invalid user
});
Response to question in comments
The above in async/await would look like this:
async function foo() {
try {
const response = await fetch('site/login', POST ...);
const responseJson = await response.json();
if (user.valid) {
return await AsyncStorage.setItem('access_token', responseJson.token);
} else {
throw new Error('Invalid user');
}
} catch (error) {
// deal with errors
}
}

Throwing a SubmissionError of redux-form causes Uncaught (in promise)

I apologize in advance for the formatting (still a newb on this), and maybe for the stupid question (still a newb on this whole React ecosystem).
I've recently picked up redux-form, and since then I've been trying to use it in the following way:
export const searchPermissions = () => {
return dispatch => {
Axios.get(`${URL}/findPermissions`)
.then(resp => {
console.log(resp.data);
dispatch({ type: PERMISSIONS_SEARCHED, payload: resp.data });
})
.catch(error => {
console.log(error);
throw new SubmissionError({
_error: "Submission error!"
});
});
};
};
And I keep getting the Uncaught error.
Searching through redux-form's github, I saw several similar problems that ended up being solved by adding the return statement (which I think I did correctly) and now I'm kinda lost.
Thanks in advance for any help.
EDIT:
I'm trying to fetch the permissions to display them in 3 combo boxes as soon as the user enters the page. In the component used to fetch the data I have the following code:
componentWillMount() {
this.props.searchPermissions();
}
render() {
return (
<div>
<LayoutGroupForm
onSubmit={this.props.addLayoutGroup}
loadPermissions={this.props.loadPermissions}
visualizationPermissions={this.props.visualizationPermissions}
detailPermissions={this.props.detailPermissions}
resetForm={this.props.resetForm}
/>
</div>
);
}
}
const mapStateToProps = state => ({
loadPermissions: state.layoutGroup.loadPermissions,
visualizationPermissions: state.layoutGroup.visualizationPermissions,
detailPermissions: state.layoutGroup.detailPermissions
});
const mapDispatchToProps = dispatch =>
bindActionCreators(
{
searchPermissions,
addLayoutGroup,
resetForm
},
dispatch
);
And on my reducer I have the following:
case PERMISSIONS_SEARCHED:
return {
...state,
loadPermissions: action.payload.loadPermissions,
visualizationPermissions: action.payload.visualizationPermissions,
detailPermissions: action.payload.detailPermissions
};
For those of you who still encounter this issue (like me), the solution is to add return to your submit handler.
Read more here
https://github.com/erikras/redux-form/issues/2269
Redux Form is expecting the error to come as the error in a rejected promise. Try this:
export const searchPermissions = () => {
return dispatch => {
return Axios.get(`${URL}/findPermissions`)
// ^^^^^^-------------------------------------- Actually return the promise!
.then(resp => {
console.log(resp.data);
dispatch({ type: PERMISSIONS_SEARCHED, payload: resp.data });
})
.catch(error => {
console.log(error);
return Promise.reject(new SubmissionError({
// ^^^^^^^^^^^^^^^^^^^^^^------------------------ Return rejected promise
_error: "Submission error!"
}));
});
};
};

Chaining Redux actions

I am new to React, Redux and JS overall. I want to know how can I dispatch and action after another is finished - Promises in correct way. My code actually works but it keeps throwing error:
readingActions.js?14b9:56 Uncaught (in promise) TypeError: dispatch(...).then is not a function(…)
This is my setup.
This is my action creator what I want chained action and where warning happends.
export function createReading(reading) {
return function (dispatch) {
dispatch({type: CREATE_READING});
return request(
`${API_URL}new`, {method: 'POST', body:JSON.stringify(reading)},
(json) => {( dispatch({type: CREATE_READING_SUCCESS, res: json}).then(dispatch(Notifications.success(showSuccess(json.book.title)))))},
(json) => { dispatch({type: CREATE_READING_ERROR400, res: json}).then(dispatch(Notifications.error(showError(json.error)))) },
(res) => { dispatch({type: CREATE_READING_ERROR500, res: res}) },
(ex) => { dispatch({type: CREATE_READING_FAILURE, error: ex}) },
)
}
}
As you can see the problem is in .then, since I dont know how to trigger action correctly.
You can also see request that is my helper function that looks like so (here I append token, return different responses):
export function request(url, options, success, error400, error, failure) {
let headers = new Headers();
headers.append("Content-Type", "application/json")
headers.append("Accept", "application/json")
options["headers"] = headers;
if (localStorage.jwtToken) {
let token = localStorage.jwtToken;
headers.append('Authorization', 'JWT '+token);
}
return fetch(url, options)
.then(res => {
if (res.status >= 200 && res.status < 300) {
res.json().then(json => {
return success(json)
})
} else if (res.status === 400) {
res.json().then(json => {
return error400(json)
})
} else {
return error(res)
}
}).catch((ex) => {
return failure(ex)
})
}
Question is how can I execute proper .then and what would be the correct way?
If you want to dispatch actions in chains you can actually implement it on your own.
Now say after analysing a bit you take a pen and paper and start write basic algorithm for how it should work and you come up with following:-
dispatch(action) => action returns function => action returns function => action returns an object(here you chain ends)
Now from above if you see that you create a middleware and keep on dispatching actions which return functions until you get an action with returns an object. This is what redux-thunk does.
So even if you try to create something of your own do that for your learning, but eventually you will come up with something like thunk or maybe some other package.
I would really say give redux-thunk a try.Also for middleware understanding I would recommend you can check redux middleware docs.

Categories

Resources