How use await keyword along with asyncstorage setitem for server response? - javascript

I'm trying to use asyncstorage in my react native app.The problem is the server response I'm getting takes some delay so I want to wait for the response then I want to use that responseData.user_id to be saved in my app.I'm using nodejs as backend and mysql db.So after user registration I'm inserting it to db at the same time I've written another query for fetching their user_id (PK).So this responseData is getting to client and I'm trying to take that user_id from the response.So I've written something like this
onPressRegister = async () => {
try {
let response = await fetch('http://192.168.1.2:3000/users/registration', {
method: 'POST',
headers: {
'Accept': 'applictaion/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
contact: this.state.contact,
password: this.state.password,
})
});
let responseData = await response.json();
if (responseData) {
try {
Action.firstScreen();
await AsyncStorage.setItem('userid', JSON.stringify(responseData.userData.phone_no));
}
catch (e) {
console.log('caught error', e);
}
}
} catch (error) {
console.error(error)
}
}
And in my next screen I'm accessing the userid like this.And passing it the next API call like this.
getUserId = async () => {
let userId = await AsyncStorage.getItem('userid');
return userId;
}
onPressYes = (workType) => {
this.getUserId().then((userId) => {
this.setState({userId:userId})
})
fetch('http://192.168.1.2:3000/users/user_request',{
method:'POST',
headers:{
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
workType,
phone:this.state.userId
})
})
.then(response => response.json())
.then((responseData) => {
this.setState({
data:responseData
});
});
}
But this is the error I'm getting.

Try this:
onPressRegister = async () => {
try {
let response = await fetch('http://192.168.1.6:3000/users/registration', {
method: 'POST',
headers: {
'Accept': 'applictaion/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
contact: this.state.contact,
password: this.state.password,
})
});
let responseData = await response.json();
if (responseData) {
try {
await AsyncStorage.setItem('userid', JSON.stringify(responseData.user_id));
}
catch (e) {
console.log('caught error', e);
}
}
} catch (error) {
console.error(error)
}
}
To access the value in some other component:
getUserId = async () => {
let userId = await AsyncStorage.getItem('userid');
return userId;
}
componentWillMount() {
this.getUserId().then((userId) => {
console.log(userId);
})
}

Related

How do I send my response in a API Route in next js when my data is in a .then promise

I am using next js with axios, and I have a .then promise inside a .then. I want to respond to the api request with the data I grabbed but if I put the res in the .then it is unreachable, but I don't know how to get the data out of the .then. Normally with async await I return the value and create a variable to the function but this does not seem to work with .then.
here is my code
let data;
axios
.post(
"https://accounts.spotify.com/api/token",
serialize({
grant_type: "client_credentials",
}),
{
headers: {
Authorization: "Basic " + auth,
},
}
)
.then((res) => {
axios
.get(
`https://api.spotify.com/v1/search?q=${name}&type=episode&market=US`,
{
headers: {
Authorization: `Bearer ${res.data.access_token}`,
"Content-Type": "application/json",
},
}
)
.then(function (response) {
// handle success
console.log(response.data.episodes);
data = response.data.episodes;
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
})
.catch((err) => {
console.log(err);
});
res.status(200).json({ data: data });
Any help would be greatly appreciated thanks
The following fixed it
const data = axios
.post(
"https://accounts.spotify.com/api/token",
serialize({
grant_type: "client_credentials",
}),
{
headers: {
Authorization: "Basic " + auth,
},
}
)
.then((res) => {
const test = axios
.get(
`https://api.spotify.com/v1/search?q=${name}&type=episode&market=US`,
{
headers: {
Authorization: `Bearer ${res.data.access_token}`,
"Content-Type": "application/json",
},
}
)
.then(function (response) {
// handle success
// console.log(response.data.episodes);
return response.data.episodes;
})
.catch(function (error) {
// handle error
console.log(error);
});
return test;
})
.catch((err) => {
console.log(err);
});
const boy = async () => {
console.log("data", await data);
res.status(200).json({ data: await data });
};
boy();

the code is doing its work but I'm not getting the desired output

whenever I click the delete button its works fine but I don't get the output like " deleted successfully " its shows .then undefined..
const deleteThisCategory = (CategoryId) => {
deleteCategory(CategoryId, user._id, token).then(data => {
if (data.error) {
console.log(data.error);
} else {
preload();
}
});
};
here is the delete category API call
export const deleteCategory = (userId, categoryId , token) => {
fetch(`${API}/category/${categoryId}/${userId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type":"application/json"
},
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
};
It should be like this. deleteCategory needs to send only promise. Later where ever you are resolving you have to use then.
export const deleteCategory = (userId, categoryId , token) => {
return fetch(`${API}/category/${categoryId}/${userId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type":"application/json"
}
})
};
const deleteThisCategory = (CategoryId) => {
deleteCategory(CategoryId, user._id, token).then(data => {
preload();
}).catch(err => {
console.log(err);
})
};

nested axios call with await in vue js

i am new to async and i have an action in vuex that get user's info and i put that in promise and i want to use this method in then block of axios call for login with await because data of user info is important for me
my problem is i cant use await in then block and error says the error says await can only be use in async function
this flow is correct and what is correct way?
store.js:
actions: {
loadUserInfo({commit}){
const headers = {
'Content-Type': 'application/json',
// 'Authorization': localStorage.getItem('access_token'),
'Accept': 'application/json'
}
return new Promise(function(resolve, reject) {
axios.get(process.env.VUE_APP_BASE_URL + process.env.VUE_APP_EDIT_INFO,{headers: headers})
.then(response => {
commit('authenticateUser');
commit('setUserInfo', response.data.result);
resolve();
})
.catch(error => {
console.log(error);
reject();
})
});
}
},
Login.vue:
async login () {
let self = this;
axios.post(process.env.VUE_APP_BASE_URL + process.env.VUE_APP_LOGIN,
this.loginInfo
).
then(function (response) {
await this.$store.dispatch('loadUserInfo').then((res)=>{
this.$emit('authenticateUser', true);
this.$emit('registeredIdentification', self.$store.getters.getUsername)
this.$router.push({ name: 'mainBox' })
});
localStorage.setItem('access_token', response.data.result.access_token)
localStorage.setItem('refresh_token', response.data.result.refresh_token)
})
.catch(function (error) {
// let statusCode = error.response.status;
console.log(error);
});
}
try moving the async declaration so it is "inside" the then:
async login () {
...
.then(async function (response) {
await this.$store.dispatch('loadUserInfo').then((res)=>{
...
}
Using then with async/await may be unnecessary:
async login() {
try {
const loginUrl = process.env.VUE_APP_BASE_URL + process.env.VUE_APP_LOGIN;
const { data } = await axios.post(loginUrl, this.loginInfo)
const { access_token: accessToken, refresh_token: refreshToken } = data.result;
await this.$store.dispatch('loadUserInfo');
this.$emit('authenticateUser', true);
this.$emit('registeredIdentification', this.$store.getters.getUsername)
this.$router.push({ name: 'mainBox' })
localStorage.setItem('access_token', accessToken)
localStorage.setItem('refresh_token', refreshToken)
} catch (error) {
console.log(error);
}
}

How to get value of async function and save it

I'm new in javascript. I've a async function getListBar. Inside getListBar i use return result of getAccount like a input of function fetch( you can see user.access_token) . Code run correct but i don't want call getAccount everytime i use getListBar. So how can i get result of getAccount and save it ?
I've tried many ways but promise very difficult to me , i don't know how to save result of it
async function getAccount() {
try {
let response = await fetch(apiAuthen,
{
method: 'POST',
headers: {
Accept: '*/*',
'Authorization': 'Basic a2VwbGxheTpva2Vwba2VwbGxaQ1YWwjJA==',
'Content-Type': 'application/x-www-form-urlencoded',
'grant_type': 'password',
},
body: qs.stringify({
'grant_type': 'password',
'username': 'abc',
'password': 'abc',
'client_id': 'abc',
})
})
let responseJson = await response.json();
return responseJson.data;
} catch (error) {
console.log(`Error is : ${error}`);
}
}
async function getListBar() {
try {
const user = await getAccount().then(user => { return user });
let response = await fetch(apiBar,
{
headers: {
'Authorization': 'Bearer ' + user.access_token
}
})
let responseJson = await response.json();
return responseJson.data;
} catch (error) {
console.log(`Error is : ${error}`);
}
}
getAccount will return a Promise like this and i want save access_token in it
Promise {_40: 0, _65: 0, _55: null, _72: null}
_40: 0
_55: {access_token: "41b369f2-c0d4-4190-8f3c-171dfb124844", token_type: "bearer", refresh_token: "55867bba-d728-40fd-bdb9-e8dcd971cb99", expires_in: 7673, scope: "read write"}
_65: 1
_72: null
__proto__: Object
If it is not possible to simply store a value in the same scope that these functions are defined, I would create a Service to handle getting the user. Preferably in its own file
AccountService.js
class AccountService {
getAccount = async () => {
if (this.user) {
// if user has been stored in the past lets just return it right away
return this.user;
}
try {
const response = await fetch(apiAuthen, {
method: 'POST',
headers: {
Accept: '*/*',
Authorization: 'Basic a2VwbGxheTpva2Vwba2VwbGxaQ1YWwjJA==',
'Content-Type': 'application/x-www-form-urlencoded',
grant_type: 'password'
},
body: qs.stringify({
grant_type: 'password',
username: 'abc',
password: 'abc',
client_id: 'abc'
})
});
const responseJson = await response.json();
this.user = responseJson.data; // store the user
return this.user;
} catch (error) {
console.log(`Error is : ${error}`);
}
// you should decide how to handle failures
// return undefined;
// throw Error('error getting user :(')
};
}
// create a single instance of the class
export default new AccountService();
and import it where needed
import AccountService from './AccountService.js'
async function getListBar() {
try {
// use AccountService instead
const user = await AccountService.getAccount().then(user => { return user });
let response = await fetch(apiBar,
{
headers: {
'Authorization': 'Bearer ' + user.access_token
}
})
let responseJson = await response.json();
return responseJson.data;
} catch (error) {
console.log(`Error is : ${error}`);
}
}
You will still be calling getAccount each time in getListBar but it will only fetch when AccountService has no user stored.
Now i write in the different way
export default class App extends Component {
constructor() {
super();
this.state = {
accessToken: '',
users: [],
listBar: []
}
}
//Get Account
Check = () => {
getAccount().then((users) => {
this.setState({
users: users,
accessToken: users.access_token
});
}).catch((error) => {
this.setState({ albumsFromServer: [] });
});
}
//Get Account
getAccount() {
return fetch(apiAuthen,
{
method: 'POST',
headers: {
Accept: '*/*',
'Authorization': 'Basic a2VwbGxheTpva2Vwba2VwbGxaQ1YWwjJA===',
'Content-Type': 'application/x-www-form-urlencoded',
'grant_type': 'password',
},
body: qs.stringify({
'grant_type': 'password',
'username': 'abc',
'password': 'abc',
'client_id': 'abc',
})
}).then((response) => response.json())
.then((responseJson) => {
this.setState({
users: responseJson.data,
accessToken: responseJson.data.access_token
});
return responseJson.data
})
.catch((error) => {
console.error(error);
});
}
//Get List Bar
getListBarFromServer() {
return fetch(apiBar, {
headers: {
'Authorization': 'Bearer ' + this.state.accessToken
}
}).then((response) => response.json())
.then((responseJson) => {
console.log(this.getListBarFromServer()) <---- Just run if console
this.setState({ listBar: responseJson.data });
return responseJson.data
})
.catch((error) => {
console.error(error);
});
}
componentDidMount() {
this.getAccount();
this.getListBarFromServer();
}
render() {
return (
<View style={{ top: 100 }}>
<FlatList data={this.state.listBar} renderItem={({ item }) => {
return (
<View>
<Text>{item.bar_id}</Text>
</View>
)
}}>
</FlatList>
</View>
)
}
}
It's just run when i console.log(this.getListBarFromServer()) .Please explain to me why?

Async/Await in fetch() how to handle errors

I have stripe async code in my React app, and trying to add error handling in my code but have no idea how to handle it. i know how to do it with .then() but async/await is new to me
EDITED
added .catch() i got errors in network tab in response tab.
but i can log it to console?
submit = async () => {
const { email, price, name, phone, city, street, country } = this.state;
let { token } = await this.props.stripe
.createToken({
name,
address_city: city,
address_line1: street,
address_country: country
})
.catch(err => {
console.log(err.response.data);
});
const data = {
token: token.id,
email,
price,
name,
phone,
city,
street,
country
};
let response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}).catch(err => {
console.log(err.response.data);
});
console.log(response);
if (response.ok)
this.setState({
complete: true
});
};
thanks
Fetch detects only network errors. Other errors (401, 400, 500) should be manually caught and rejected.
await fetch("/charge/pay", headers).then((response) => {
if (response.status >= 400 && response.status < 600) {
throw new Error("Bad response from server");
}
return response;
}).then((returnedResponse) => {
// Your response to manipulate
this.setState({
complete: true
});
}).catch((error) => {
// Your error is here!
console.log(error)
});
If you are not comfortable with this limitation of fetch, try using axios.
var handleError = function (err) {
console.warn(err);
return new Response(JSON.stringify({
code: 400,
message: 'Stupid network Error'
}));
};
var getPost = async function () {
// Get the post data
var post = await (fetch('https://jsonplaceholder.typicode.com/posts/5').catch(handleError));
// Get the author
var response = await (fetch('https://jsonplaceholder.typicode.com/users/' + post.userId).catch(handleError));
if (response.ok) {
return response.json();
} else {
return Promise.reject(response);
}
};
You can either use try/catch just like normal, imperative programming:
try {
let response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
} catch(error) {
// Error handling here!
}
Or you can mix-and-match .catch() just like you do with promises:
let response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}).catch(function(error) {
// Error handling here!
});
Wrap your await with try catch.
try {
let response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
console.log(response);
} catch (error) {
console.log(error);
}
This works if server returns { message: "some error" } but I'm trying to get it to support res.statusText too:
const path = '/api/1/users/me';
const opts = {};
const headers = {};
const body = JSON.stringify({});
const token = localStorage.getItem('token');
if (token) {
headers.Authorization = `Bearer ${token}`;
}
try {
const res = await fetch(path, {
method: opts.method || 'GET',
body,
headers
});
if (res.ok) {
return await (opts.raw ? res.text() : res.json());
}
const err = await res.json();
throw new Error(err.message || err.statusText);
} catch (err) {
throw new Error(err);
}
async function loginWithRedirect(payload: {
username: string;
password: string;
}) {
const resp = await (await fetch(`${env.API_URL}/api/auth/login`, {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(payload),
credentials: "include",
})).json();
if (resp.error) {
dispatch({type: "ERROR", payload: resp.error.message});
} else {
dispatch({type: "LOGIN", payload: resp});
}
}
If response.ok is false you can throw an error then chain catch method after calling your function as follows
async function fetchData(){
const response = await fetch("/charge/pay", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
if(!response.ok){
const message = `An error occured: ${response.status}`;
throw new Error(message);
}
const data = await response.json();
return data;
}
fetchData()
.catch(err => console.log(err.message));
I write promise function for using fetch in async await.
const promisyFetch = (url, options) =>
new Promise((resolve, reject) => {
fetch(url, options)
.then((response) => response.text())
.then((result) => resolve(result))
.catch((error) => reject(error));
});
By the way i can use it easly in async with try catch
const foo = async()=>{
try {
const result = await promisyFetch('url' requestOptions)
console.log(result)
} catch (error) {
console.log(error)
}
}
It was simple example, you could customize promisyFetch function and request options as you wish.
const data = {
token: token.id,
email,
price,
name,
phone,
city,
street,
country
};
axios
.post("/charge/pay", data)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err.response.data);
});

Categories

Resources