Problem With Fetch Calls And Promise Chaining
Solution 1:
Good for you to take a step back and really focus on learning the basics. You should know that fetch
is a low-level interface and it's a rookie move to use it as-is. Programming is all about making your life easier. If you need to deal with JSON, let's write a fetchJSON
specialization -
constfetchJson = (url, opts = {}) =>
fetch(url, { ...opts, headers: 'Content-Type': 'application/json' })
.then(r => r.json())
Even with our helper, we shouldn't jump to use it directly. By defining reusable functions, our code becomes more descriptive and easier to use -
constuserList = () =>
fetchJson(`http://localhost:8080/users/all`)
Creating the userRegister
function is easy too -
constuserRegister = (user = {}) =>
fetchJson
( `http://localhost:8080/users/register`
, { method: "POST", mode: "cors", body: JSON.stringify(user) }
)
And finally userDelete
-
constuserDelete = email =>
fetchJson
( `http://localhost:8080/users/delete-email/${email}`
, { method: "DELETE", mode: "cors" }
)
Now we can put it all together
consttest = () =>
userRegister({
firstName: 'nick',
lastName: 'smith',
phone: '01980635243',
email: 'nick@hotmail.com',
password: '1234567891011',
confirmPassword:'1234567891011'
})
.then(user => {
console.log("registered", user)
returnuserList()
})
.then(users => {
console.log("list", users)
returnuserDelete("nick@hotmail.com")
})
.then(_ =>console.log("user deleted")
returnuserList()
})
Notice we don't attach any .catch
to the test
. This is left for the caller to decide. We could run the test like this -
test().then(console.log, console.error)
don't stop there
Do you see the pattern of .then(something => { console.log(something), ... })
. We could make a generic log
function that makes this intention more clear -
constlog = label => data =>
{ console.log(label, data)
return data
}
consttest = () =>
userRegister({
firstName: 'nick',
lastName: 'smith',
phone: '01980635243',
email: 'nick@hotmail.com',
password: '1234567891011',
confirmPassword:'1234567891011'
})
.then(log("registered"))
.then(_ =>userList())
.then(log("list"))
.then(_ =>userDelete("nick@hotmail.com"))
.then(log("user deleted"))
.then(_ =>userList())
But there's a bad practice here. console.log
is a side effect and it would be nice if we could get the result of each promise back from the test
. We can plainly see that _ => ...
is replacing the value of the previous promise in the chain and only the final promise value will be available to the caller.
You could append all the results to an array and thread the array through to each successive promise, but this is also rather tedious. This is particularly where async
and await
are helpful as they make promise values available in the same scope -
asyncfunctiontest()
{ const user = awaituserRegister({
firstName: 'nick',
lastName: 'smith',
phone: '01980635243',
email: 'nick@hotmail.com',
password: '1234567891011',
confirmPassword:'1234567891011'
})
const list1 = awaituserList()
constdelete = awaituserDelete("nick@hotmail.com")
const list2 = awaituserList()
return [user, list1, deleted, list2] // <- all results
}
Now console.log
has been disentangled from test
and the result of all promise values is available to the caller
test().then(console.log, console.error)
Post a Comment for "Problem With Fetch Calls And Promise Chaining"