繁体   English   中英

在第一个表返回的条件条件或从foreach派生为空的数组中返回对象值的条件下进行联接

[英]Sequelize join on where condition returned from first table or return object values in an array derrived from foreach coming up empty

我已经尝试解决了一段时间,因此非常感谢您的帮助。

我有一个名为“交互”的表,该表使用客户端用户的ID进行搜索,并返回所有作为目标用户的交互。 然后,我想返回通过User表发起交互的那些用户的名称。

我尝试使用include来联接User表,但无法使用where子句获取用户名,因为它基于在Interaction表的第一次搜索中返回的值,并且不知道我是否可以搜索一个值那不是主键还是那样?

我得到的最接近的结果是使用foreach并将用户添加到数组中,但是我无法在响应中返回该数组,因为在循环之外它为空。 我已经尝试过找到的建议,但是如果这是最好的选择,则无法弄清楚如何在foreach之外返回数组。 我确信这对我来说确实是愚蠢的。 TIA。

这是我尝试的包含功能:

getInvited: (req, res, next) => {
    var user = {}
    user = req.user;
    let usrId = user[0]['facebookUserId'];
    var userObjArray = [];
    Interaction.findAll({
        where: {
            targetUserId: usrId,
            status: 'invited',
        },
        include: [{
            model: User,
            attributes: [
                'firstName'
            ],
            where: {
                facebookUserId: IwantToJoinOnInteraction.userId // replace with working code?
        }]
    }).then(function (users) {
        res.send(users);
    }).catch(next);
}

或者我尝试foreach:

getInvited: (req, res, next) => {
    var user = {}
    user = req.user;
    let usrId = user[0]['facebookUserId'];
    var userObjArray = [];
    Interaction.findAll({
        where: {
            targetUserId: usrId,
            status: 'invited',
        }
     }).then(function (interactions) {
         interactions.forEach((interaction) => {
             User.findOne({
                 where: {
                     facebookUserId: interaction.userId // this is the where clause I don't know how to add in my first attempt with include
                 },
                 attributes: ['firstName', 'facebookUserId']          
             }).then(function (user) { 
                 userObjArray.push(user['dataValues']);
                 console.log(userObjArray); // on the last loop it contains everything I need
             })
         })
         res.status(200).send(userObjArray); // empty
    }).catch(next);
},

您必须等待所有承诺,然后再发送响应。 您的代码异步运行。 使用forEach您正在异步调用User.findOne但您不必等待所有User.findOne完成。 Promise.all是实现此工作的一种简便方法。 您可以传递一个promise数组,然后将返回的promise解析为所有已解析promise的数组。

Promise.all(interactions.map(interaction => User.findOne(...)))
  .then(users => {
    res.status(200).send(users.map(user => user.dataValues))
  })

您可以编写更容易阅读的异步/等待方式

getInvited: async (req, res, next) => {
  ...
  const interactions = await Interaction.findAll(...)
  const users = await Promise.all(interactions.map(interaction => User.findOne(...)))
  res.status(200).send(users.map(user => user.dataValues))
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM