Reputation: 716
I am trying to query the Twitter API for users' followers to compare the two. I am using a cursor to retrieve the list of users. I set it up using promises, where the first get request gets the users followers to a limit, then looks for the cursor passes the data into an array and then resolves with the value of the cursor into a the same recurring function until the cursor returns 0, when that happens I want to send it all in a res. When I set up my initial promises and use promise.all
to resolve them and attach a .then
, the promise. all resolves first. I've tried resolving the promise from the recurring function and then returning another promise to the first function but I can't seem to get it to work. Any ideas?
const express = require("express");
const router = express.Router();
const twitter = require("../controllers/twitter");
let object1 = {
params: {
screen_name: "xxxx",
count: "40"
}
};
let object = {
params: {
screen_name: "xxxxx",
count: "40"
}
};
let data = [];
router.get("", (req, res, next) => {
let one = getUserFollowers("/1.1/followers/ids.json", object);
let two = getUserFollowers("/1.1/followers/ids.json", object1);
Promise.all([one, two]).then(console.log);
});
function getUserFollowers(uri, parameters) {
twitter
.get(uri, parameters)
.then(resp => {
let ids = resp.data.ids;
data.push(...ids);
return recurr(resp, uri, parameters);
})
.then(data => {
//if instead I re console.log the data I can get it, but I need to resolve it back in the router so I can send it as a res.
return new Promise((resolve, reject) => {
resolve(data);
reject(error);
});
});
}
let recurr = (response, uri, params) => {
if (response.data.next_cursor > 0) {
params.params.cursor = response.data.next_cursor;
return getUserFollowers(uri, params);
} else {
return Promise.resolve(data);
}
};
module.exports = router;
Upvotes: 0
Views: 515
Reputation: 6264
The mistakes in your code:
getUserFollowers
doesn't return anything - so, lets add a return before twitter.get
.then(data => {
//if instead I re console.log the data I can get it, but I need to resolve it back in the router so I can send it as a res.
return new Promise((resolve, reject) => {
resolve(data);
reject(error);
});
});
This makes no sense for several reasons.
.then
always returns a promise, so there's usually no need for a Promise constructor when the .then contains only synchronous code; anddata
in .then, done nothing to it, and in a complicated way, returned data out the other endSince recurr
is only ever called inside a .then
you don't need to guarantee you're returning a Promise using Promise.resolve
- however, I'd lose the recurr function altogether, it just complicates things in such simple code
he fact that you have one global data
variable that has data pushed by both getUserFollowers
will probably cause you problems too
Rewriting to fix all of the above, you get:
const express = require("express");
const router = express.Router();
const twitter = require("../controllers/twitter");
let object1 = {
params: {
screen_name: "xxxx",
count: "40"
}
};
let object = {
params: {
screen_name: "xxxxx",
count: "40"
}
};
router.get("", (req, res, next) => {
let one = getUserFollowers("/1.1/followers/ids.json", object, []);
let two = getUserFollowers("/1.1/followers/ids.json", object1, []);
Promise.all([one, two]).then(console.log);
});
function getUserFollowers(uri, parameters, data) {
return twitter
.get(uri, parameters)
.then(resp => {
let ids = resp.data.ids;
data.push(...ids);
if (resp.data.next_cursor > 0) {
params.params.cursor = response.data.next_cursor;
return getUserFollowers(uri, params, data);
}
return data;
});
}
module.exports = router;
Upvotes: 1