If the promise chain returns a promise, it will call the next then (or catch) with the resolved (or rejected) value of that promise. If it doesn't, then it'll just call the next then with the returned value (or undefined if nothing was returned):
const myPromise = myApiCall().then(response => {
return anotherApiCallThatReturnsAPromise(response);
}).then(secondResponse => {
// this is the resolved value of anotherApiCall...
return secondResponse;
}).catch(err => {
// this error could be because myApiCall failed or because anotherApiCall... failed
})
const myPromise = myApiCall().then(response => {
return 42
}).then(value => {
// value is 42
}).catch(err => {
// this error, if present, is because myApiCall failed
})
Extrapolating, let's return nothing from the first callback:
const myPromise = myApiCall().then(response => {
// notice we do not return anything here
// we just call a function - i.e. return undefined
doSomeWorkAndReturnNothing();
}).then(value => {
// value is undefined because nothing was returned from the previous `then`
}).catch(err => {
// this error, if present, is because myApiCall failed
})
Just for fun, here's what is looks like using await in an async function:
const myFunc = async () => {
try {
const response = await myApiCall();
const secondResponse = await anotherApiCallThatReturnsAPromise(response);
return secondResponse;
} catch(err) {
// this error could be because either of the previous two await-ed calls failed
}
}