Can I reduce this asynchronous code using built in fetch()? - javascript

There seems to be an extra then method
getUser () {
const options = {
credentials: 'include'
};
fetch("/api/user", options)
.then((response) => {
return response.json();
})
.then((results) => {
console.log(results);
})
.catch((err) => {
});
I would like to reduce to:
getUser () {
const options = {
credentials: 'include'
};
fetch("/api/user", options)
.then((response) => {
console.log(response.json());
})
.catch((err) => {
});
Wrather than just test it out and see if it works I would like to try and understand why it was written the first way an if it is good practice.
Update
Why are their two promises for only 1 asynchronous event?
Should not parsing JSON be a simple synchronous function call?
Or is this just a design choice that we can make any function asynchronous?

response.json() returns a promise. Their version logs out the result of that promise. Your version would log out the promise object in a pending state, not the value it resolves to.

Related

How to put a fetch request inside a function and wait for the return value when I call the function

I am using react-native, mongo DB and node js and I need to create some database functions and put them in some modules to be able to reuse them whenever I want. To fetch data from the mongo database, I use the fetch() function which returns a promise. So, for all functions that I created that did not return a value, I used .then and I faced no problems. On the other side, when I return a value inside a fetch().then() function and use this returned value, I get undefined. The code I use for the function looks like:
export const getUsers = () => {
//I cannot use this function because of returning a promise
fetch("http://1jjsd12zaws.ngrok.io/database/", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
})
.then((res) => {
res.json();
})
.then((data) => {
return JSON.stringify(data);
});
};
Then, when I try to run this code:
let users=getUsers();
console.log(users);
It prints undefined.
What I think is going on is that the console.log(users) runs before getUsers() returns its value. But I do not know why does this happen and I want it to wait for getUsers() to execute then, completes its work.
You need to return fetch(..) inside getUsers (that's why you are getting undefined)
You also need to return res.json() inside the first then
Since getUsers returns a Promise, then you need to use .then (or async/await) to access the promise value: getUsers().then(users => {...})
const getUsers = () => {
return fetch('http://1jjsd12zaws.ngrok.io/database/', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(res => {
return res.json();
})
.then(data => {
return JSON.stringify(data);
});
};
getUsers().then(users => console.log(users))
Async and await should cover it. The example on MDN docs explains it better than I can and should apply to your use case.

Why use a promise when making an axios api call?

I was following a vue.js tutorial and saw something that confuses me and was wondering if someone can explain it to me since I never use promise. The below method is used to assign a customer array object. Why use a Promise? I thought Promise should be used when you are returning an object to a service consumer? Why and when should I use a promise?
loadCustomer() {
new Promise((resolve, reject) => {
axios.get(this.DetailsDataUrl)
.then(res => {
this.Customer = res.data
resolve()
})
.catch(err => {
console.log(err);
reject()
})
});
}
With promises you can call asynchronous functions.
e.g. here when you want to use loadCustomer you can await until this function resolve or reject:
try {
// resolve
const response = await loadCustomer()
} catch(err) {
// reject
console.log(err)
}
axios it self return a promise:
so you can rewrite your function like this:
loadCustoemr() {
return axios.get(this.DetailsDataUrl)
}
and call it:
loadCutomer()
.then(res => this.Customer = res.data)
.catch(err => console.log(err))
as above you can also use async/await here.
for more information you can use this link,

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
}
}

How to return the json response from the fetch API

I have a function like so:
check_auth(){
fetch(Urls.check_auth(), {
credentials: 'include',
method: 'GET'
}).then(response => {
if(response.ok) return response.json();
}).then(json => {
return json.user_logged_in;
});
}
And then I try to do this:
if(this.check_auth()){
// do stuff
} else {
// do other stuff
}
But, this.check_auth() is always undefined.
What am I missing here? I thought that within fetch's then() was where the resolved Promise object was therefore I thought that I'd get true when the user was logged in. But this is not the case.
Any help would be greatly appreciated.
Use callback
check_auth(callback){
fetch(Urls.check_auth(), {
credentials: 'include',
method: 'GET'
}).then(response => {
if(response.ok) return response.json();
}).then(json => {
callback(json.user_logged_in);
});
}
check_auth(function(data) {
//processing the data
console.log(d);
});
In React it should be easier to handle, You can call a fetch and update the state, since on every update of state using setState the render method is called you can use the state to render
check_auth = () =>{
fetch(Urls.check_auth(), {
credentials: 'include',
method: 'GET'
}).then(response => {
if(response.ok) return response.json();
}).then(json => {
this.setState({Result: json.user_logged_in});
});
}
it can be solved with the es6 aync functions
Note: the example is different from what OP asked but it gives some hints on how it should be done
const loadPosts = async () => {
const response = await fetch(/* your fetch request */);
const posts = await response.json();
return posts;
};
Async calls doesn't always resolve to be used anywhere within your app when you use .then(). The call is still async and you need to call your if-statement when you are calling your fetch. So anything that relies on the data you are fetching has to be chained to the fetch with .then().
check_auth(){
fetch(Urls.check_auth(), {
credentials: 'include',
method: 'GET'
}).then(response => {
if(response.ok) return response.json();
}).then(json => {
return json.user_logged_in;
}).then(user => checkIfAuthSuccess(user)); //You have to chain it
}
Wrapping your if-statement in a function or however your code looks like.
checkIfAuthSuccess(user){
if(user){
// do stuff
} else {
// do other stuff
}
}
Nice video about async behavior in JavaScript: Philip Roberts: What the heck is the event loop anyway? | JSConf EU 2014
To return data as JSON from Promise you should call it with await modifier from async function.
For example:
const checkAuth = async () => {
const data = await fetch(Urls.check_auth())
.then(response => response.json())
.then(json => json.user_logged_in)
return data;
}
More info about promises you can find here

Categories

Resources