For a unit test I am creating a new user via POST in my database, retrieving a id and token. After that I want to DELETE this user with the id, token I just received from the first fetch.
import fetch from 'node-fetch';
type Response = {
status: number,
body: any
};
const response = {} as Response;
someFunction(async () => {
// Create new user
await fetch('http://localhost:3000/api/user/register', {
method: 'POST',
body: JSON.stringify({email: 'user@test.com', password: 'test-password'}),
headers: {'Content-Type': 'application/json'}
}).then(res => {
res.json().then(json => response.body = json);
}
);
// Delete user just created
await fetch('http://localhost:3000/api/user/' + response.body.id, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + response.body.token
}
});
});
The first fetch runs successfully response.body.id
and response.body.token
are not empty but the second fetch always fails anyways with TypeError: Cannot read property 'id' of undefined
I would appreciate if someone could point out why. Thanks
The reason it happens is because you're mixing up some methods. When your first fetch fulfills it will call the first then()
method. Inside of that you call the json()
method of the response and chain the promise from there. Now the first then()
did not get a returned value, so the fetch
thinks it's finished. But in reality your res.json()
promise could still be running.
All the while your second fetch
request is already being called while res.json()
is still resolving. That's why the value is undefined
.
So await the first fetch and store the response. Then await the json()
promise and store the result of that. Now your thread goes through each step without having a race condition.
The values from the JSON response will now be available in your second fetch
request.
The second fetch
doesn't have to use await
. Only if you need the values from the response and need to do something whenever that request finishes.
someFunction(async () => {
// Create new user
const response = await fetch('http://localhost:3000/api/user/register', {
method: 'POST',
body: JSON.stringify({email: 'user@test.com', password: 'test-password'}),
headers: {'Content-Type': 'application/json'}
});
const json = await response.json();
// Delete user just created
fetch('http://localhost:3000/api/user/' + json.id, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + json.token
}
});
});