Faiyaz Shaikh
Faiyaz Shaikh

Reputation: 127

Using promises in a javascript filter function and returning it

I am trying to return an array of everyone session (me) is not following with JavaScript's filter function with the help of a promise and sending it as a JSON response.

But it doesn't work.

Thanks in advance!!

app.get('/explore', (req, res) => {
  P.coroutine(function *(){
    let
        { id: session } = req.session,
        followings = yield db.query('SELECT id, username, email FROM users WHERE id <> ? ORDER BY RAND() LIMIT 10', [session]),
        d = followings.filter(e => {
            db.is_following(session, e.id).then(s => s )   // returns boolean
        })

        res.json(d)
  })()
})

Upvotes: 0

Views: 1468

Answers (2)

Faiyaz Shaikh
Faiyaz Shaikh

Reputation: 127

Adam's solution worked very well, but I have found another solution which uses async/await.

Code is much less and human-readable!!

app.post('/explore', async function(req, res) {
  let
  { id: session } = req.session,
  exp = [],
  followings = await db.query(
   'SELECT id, username, email FROM users WHERE id <> ? ORDER BY RAND() LIMIT 10', 
   [session]
  )

  for (let f of followings) {
    let is = await db.is_following(session, f.id)
    !is ? exp.push(f) : null
  }

  res.json(exp)

})

Upvotes: 0

Adam Jenkins
Adam Jenkins

Reputation: 55613

Array.prototype.filter is synchronous - you can't filter an array with an asynchronous filter.

What you can do, is create an array of Promises and then when all of them are resolved, return the response:

var promises = [];
var d = [];
followings.forEach(function(e) {
  promises.push(
    db.is_following(session,e.id).then(function(s) {
      //following, push e onto `d`
      d.push(e);
    }).catch(function() {
      //not following, I assume, do nothing
    })
  );
});

Promise.all(promises).then(function() {
  //send the response after all the is_following requests have finished
  res.json(d);
});

Upvotes: 1

Related Questions