Open panzerdp opened 3 years ago
bows
const result = *await* fetch(...
saved my day!
Ah! I cannot edit. But, thanks for actually the await
with the call to result.json()
Ah! I cannot edit. But, thanks for actually the
await
with the call toresult.json()
You're welcome @neillindberg. It was a surprise for me too that result.json()
returns a promise!
By the way, you can edit your comment on GitHub.
Great write-up! I'm dropping a link to MDN API for Response just in case anyone wants to know more https://developer.mozilla.org/en-US/docs/Web/API/Response
Great write-up! I'm dropping a link to MDN API for Response just in case anyone wants to know more https://developer.mozilla.org/en-US/docs/Web/API/Response
Thanks! Good idea about the Response link.
Very helpful article and good approaches
Very helpful article and good approaches
Thanks @AlexRToledo.
Wooooooow!!!! Awesome article! Never read anything so clear about fetch and so much in depth. Thank you very much!
Wooooooow!!!! Awesome article! Never read anything so clear about fetch and so much in depth. Thank you very much!
You're welcome @rowild.
return await response.json(); in title image?
Cool article btw. ;)
return await response.json(); in title image?
@BenjaminDaSilva Why not?
Isn't the return await inside an async function redundant, as it returns a promise implicitly? So there's no observable difference but maybe a memory overhead because of an intermediate promise?
Also see this discussion: https://stackoverflow.com/a/42750371
Isn't the return await inside an async function redundant, as it returns a promise implicitly? So there's no observable difference but maybe a memory overhead because of an intermediate promise?
Also see this discussion: https://stackoverflow.com/a/42750371
Yes, most of the time it doesn't make a difference.
However:
await
before a promise, as a good discipline. Even in a return statement.response.json()
is an async method that returns a promise when parses JSON.Cool article btw. ;)
Thanks!
@panzerdp,
in your first mail response I've received a more in depth explanation on why you prefer using the await here, I find this valuable additional information, hope it's OK to quote it here:
"By using await response.json() I want the potential error thrown by response.json() (in case if the server returns invalid JSON) to be thrown from inside of fetchMovies() function. That would give a more accurate stack trace of the error, particularly it will indicate that error has happened inside the fetchMovies()."
Hi, great article! Let's say that I would retry your Promise.all code X times before it throws an error, how would you do it?
@jetolu - I think you could use Promise.allSettled() in fetchMoviesAndCategories() and in the then-function check with an if-condition if one of them has returned rejected status, in which case you can have a number of retries per rejected promise with an async/await while loop for instance until the maximum number if retries has been reached.
thanks 🤗
approach you mentioned for error handling is not handling 404 though
approach you mentioned for error handling is not handling 404 though
@pavanjoshi914 Can you provide more details or a demo?
Thanks, well written article :D
Thanks, well written article :D
Thanks @AhmedEzzat12!
approach you mentioned for error handling is not handling 404 though
@pavanjoshi914 Can you provide more details or a demo?
Great article @panzerdp ! regarding using fetch API article is great :tada:. In my case I shifted with ES6 methods for loading as fetch API wont play good in offline apps!
Can I use fetch to get data from that already has a .json extension?. For example, I am working on a project that already has a data.json supplied to me? Can I import that to my project with fetch?
@sukodes ,
sure, for example (excerpt from a vue project of mine):
async fetchConfigFile() { const confFile = await fetch("config.json"); const confJson = await confFile.json(); return confJson; }
After assigning the response.json() to a const or var you have an object and can also reach it's properties regularly like confJson.property1 or confJson.array1[3] or sth.
How do I check for errors in the : const movies = await response.json(); process?
@mkc73, here is a generic apiCall method as example:
const apiCall = async (method, url, authString, payload) => {
const response = await fetch(url, {
method: method,
headers: {
Authorization: authString,
'Content-Type': 'application/json'},
body: JSON.stringify(payload)
});
if (!response.ok) {
const message = `An error has occured: ${response.status} - ${response.message}`;
throw new Error(message);
}
const r = await response.text();
return r ? JSON.parse(r) : {};
}
I may be confused about what is happening with fetch but my question was that in the async function there are two await function calls - errors in the the first are caught by checking response.ok - can there subsequently be an error in the second call and if so what is the syntax for checking and reporting it ? The code above fails gracefully without reporting an error.
Many thanks for your great article and response.
@mkc73 , not sure if you're referring to my code sample or @panzerdp's movie code sample, could you elaborate a bit, maybe including the code sample you're referring to?
By "two await function calls in the async funtion", you mean the response.text() method of the fetch API? If so, I presume the text() method also throws an error if sth. goes wrong and you can catch that error when calling the function and do with it whatever you want, like:
const myResult = await apiCall('GET', 'https://myApi/myResource').catch(error => {
console.log(error.message);
// any other code doing sth. with the error message
});
@mkc73 , I think I get what you mean now, in my example, if r is undefined, an empty object is returned with that ternary operator. I think one could just add a catch block:
const apiCall = async (method, url, authString, payload) => {
const response = await fetch(url, {
method: method,
headers: {
Authorization: authString,
'Content-Type': 'application/json'},
body: JSON.stringify(payload)
});
if (!response.ok) {
const message = `An error has occured: ${response.status} - ${response.message}`;
throw new Error(message);
}
const r = await response.text().catch(error => {
throw new Error(error);
});
return r;
}
Hello. Good Tutor, thans!!!
But... how does it work with Class???
Need to store async fetch result in the cvariable..... but after creation instance of class Class Authorization variable CSRF_KEY is Inderfined (((((
Class Authorization { constructor() { this.get_token().then((data) => { this.CSRF_KEY = data.CSRF_KEY }) }
async get_token(options = {}) {
let response = await fetch('token.php', options);
return await response.json();
}
}
let auth = new Authorization( {} ) console.log( auth.CSRF_KEY ) // UNDEFINED
@raldugin , you might want to read this: https://dev.to/somedood/the-proper-way-to-write-async-constructors-in-javascript-1o8c
@BenjaminDaSilva Thanks a lot!!!!!
@BenjaminDaSilva You save my mind )))
Thanks! You helped me a lot.
I've been searching for 2 days for such clear explanation. I was able to do the call through ajax but I wanted to understand fetch() and Promise()... https://javascript.info/fetch did not work! .then() chaining https://dev.to/ramonak/javascript-how-to-access-the-return-value-of-a-promise-object-1bck. is not clear. Cannot figure out how to do deal with geoJsonObject fetched!
@openHBP, some code samples would have been helpful, so some guesses / hints
fetch returns a stream, you have to apply on of the builtin methods like .json() or .text() to the response to have an "actionable" response
fetch returns a promise, so an async response, either you have to make your function async and await the response or resolve the promise. When using .then(), JS implicitly resolves the promise in the 2nd then block:
fetch('https://www.boredapi.com/api/activity',
{
method: 'GET'
}).then(
response => {
const r = response.json();
console.log(r); // pending promise
return r;
},
error => {
console.log(error);
}
).then( json => {
// in the 2nd .then() the promise is resolved
console.log(json);
})
Or you just use an async success callback in the then block:
fetch('https://www.boredapi.com/api/activity',
{
method: 'GET'
}).then(
async response => {
const r = await response.json();
console.log(r); // returns resolved promise, so the repsonse as json
},
error => {
console.log(error);
}
)
Many thanks but it worked fine with the explanations of the blog https://dmitripavlutin.com/javascript-fetch-async-await/. The links I mentioned is about examples that didn't work for me. Your blog is crystal clear and I achieved to do it and your last 2 examples make things even clearer! Thanks again.
@openHBP ,
it's not my blog, I'm just a random dude commenting here =)
But I agree - kudos to @panzerdp for this nice blog.
Very good post, thank you.
You mention at some point that
When I was familiarizing with fetch(), I was surprised that fetch() doesn't throw an error when the server returns a bad HTTP status,
This actually makes sense: the fetch()
command was successful because the web server responded successfully. What the response was is not a concern for fetch()
- it did its job and everything was fine.
The server responded that it could not serve the content (response value ≥ 300) for some reason. Why exactly the content could not be served is more or less described by the return code (404 in the case of /oops
). The codes are not written in stone, you could respond with a 200 to say that the database is missing but it would be confusing, especially if someone relies on the codes to make a decision.
There are more and more web services that rely only partially on the codes. They would for instance send back a 200 (OK), a 400 (something wrong on your side), and a 500 (something is wrong on my side) - and provide detailed information as part of the response. It will allow the client to make more reasonable decisions (I must back off, I need to add an extra foo
parameter, ...).
OTOH, a failure to even reach the web server will cause fetch
to fail and the problem must be further investigated. In any case, this is not good news because of an organic problem with the connection. The client's reaction will be different and often requires human intervention (or just retry and hope for the best if this seems to be "network related" (as opposed to, say, a typo in the URI)
Written on 09/11/2020 07:17:46
URL: https://dmitripavlutin.com/javascript-fetch-async-await/