const PAGESIZE = 1000;
const DEFAULTLINK = `${URL}/stuff?pageSize=${PAGESIZE}&apiKey=${APIKEY}`;
export const getAllStuff = (initialLink = DEFAULTLINK) => {
let allStuff = {};
return getSuffPage(initialLink)
.then(stuff => {
allStuff = stuff;
if (stuff.next) {
return getAllStuff(stuff.next)
.then(nextStuff => {
allStuff = Object.assign({}, stuff, nextStuff);
return allStuff;
});
} else {
return allStuff;
}
});
};
const getSuffPage = nextPageLink => {
fetch(nextPageLink).then(res => {
return res.json();
});
};
Calling getAllStuff throws:
Possible Unhandled Promise Rejection (id: 0): TypeError: Cannot read property 'then' of undefined TypeError: Cannot read property 'then' of undefined at getAllStuff
I think it is usually because I do not return from a promise then or something but where don't I?
I've been working with anamorphisms or
unfold
in JavaScript lately and I thought I might share them with you using your program as a context to learn them inTo demonstrate that this works, we introduce a fake
fetch
and databaseDB
with a fakedelay
of 250ms per requestNow we just run our program like this
And finally, here's
asyncUnfold
Program demonstration 1
Now say you wanted to collapse the result into a single object, we could do so with a
reduce
– this is closer to what your original program does. Note how thenext
property honors the last value when a key collision happensIf you're sharp, you'll see that
asyncUnfold
could be changed to output our object directly. I chose to output an array because the sequence of the unfold result is generally important. If you're thinking about this from a type perspective, each foldable type's fold has an isomorphic unfold.Below we rename
asyncUnfold
toasyncUnfoldArray
and introduceasyncUnfoldObject
. Now we see that the direct result is achievable without the intermediatereduce
stepBut having functions with names like
asyncUnfoldArray
andasyncUnfoldObject
is completely unacceptable, you'll say - and I'll agree. The entire process can be made generic by supplying a typet
as an argumentNow if we want to build an array instead, just pass
Array
instead ofObject
Of course we have to concede JavaScript's deficiency of a functional language at this point, as it does not provide consistent interfaces for even its own native types. That's OK, they're pretty easy to add!
Program demonstration 2
Finally, if you're fussing about touching properties on the native
Array
orObject
, you can skip that and instead pass a generic descriptor in directly