基于对象值中的键更新猫鼬中的对象数组

Updating array of objects in mongoose based off key in objects value

我有两个 ejs 表单,当它们被点击时,向我的 /api/users/makePicks/:id 路由发出 HTTP post 请求。这条路线到达我的控制器,它使用他们在 EJS 表单中提交的 NFL 选秀权更新我 mongodb 中的用户模型。

我需要这条路线来为每条路线创建精选对象,如果它们在那个特定的星期不存在,如果它们确实存在,它需要更新已经存在的精选对象。这些选择被存储在我的用户模型中的一个数组中,这个数组包含每周选择的对象。目前,在 Mohammed 的大力帮助下,代码已成功将代码推送到数组。但是我似乎无法弄清楚如果存在具有该周密钥的对象,如何更新选择。

我的验证终于可以正常工作了。我的意思是我们在 picks 数组上 运行 一个 for 循环,它会 console.log 如果已经有一个匹配的 picks 对象与那个星期的 picks ,如果对象具有第一个键值与当前周表格不存在,它将 console.log false 并将新的选择推送到数组。

唯一不起作用的部分是嵌套在我的 for 循环中的 if 语句,如果它已经存在于 picks.array 中,它不会更新对象。但正如我所说,验证工作正常。我怀疑代码行

result.picks[i] = { [`week-${req.params.week}`]:req.body };

出于某种原因没有用更新后的 req.body.

更新对象

控制器

exports.makePicks = async (req, res, next) => {
  const picks = req.body;
  try {
   
    let result = await User.findById(req.user._id);
    
    if (result.picks.length > 0) {
      for (let i = 0; i < result.picks.length; i++) {
        if ((Object.keys(result.picks[i])[0] == [`week-${req.params.week}`])) {
          console.log(chalk.green("true"));
          result.picks[i] = { [`week-${req.params.week}`]:req.body };
          break;
        } else {
          console.log(chalk.red("false"));
          result.picks.push({ [`week-${req.params.week}`]: picks });
          break;
        }
      }
    } else {
      result.picks.push({ [`week-${req.params.week}`]: picks });
      console.log(chalk.yellow('results.picks is empty'))
    }

    
    await result.save();
    res.redirect("/api/dashboard");

  } catch (error) {
    console.log(error);
  }
};

result.picks 示例结构

[{"week-1":
    {"jojo-0":"ARI","jojo-1":"ARI","jojo-2":"ARI"}
},
{"week-2":
    {"jojo-0":"ATL","jojo-1":"ATL","jojo-2":"BAL"}
},
{"week-3":
    {"jojo-0":"ARI","jojo-1":"ARI","jojo-2":"ARI"}
}]

路由器

router.route('/makePicks/:week')
  .post(controller.makePicks);

EJS

<% const teamsArr = ['ARI', 'ATL', 'BAL', 'BUF', 'CAR', 'CHI', 'CIN', 'CLE', 'DAL', 'DEN', 'DET', 'GB', 'HOU', 'IND', 'JAX',
'KC', 'LAC', 'LAR', 'LV', 'MIA', 'MIN', 'NE', 'NO', 'NYG','NYJ', 'PHI', 'PIT', 'SEA', 'SF', 'TB', 'TEN', 'WAS' ] %>

<form class="mt-3 mb-3" method="POST" action="/api/users/makePicks/1">
  <% for(i=0; i < user.bullets; i++){ %>
  <div class="form-group">
    <label for="<%= `${user.name}-${i}` %>">Make your pick for bullet <%= `${i}` %></label>
    <select class="form-control" name="<%= `${user.name}-${i}` %>" id="<%= `${user.name}-${i}` %>">
      <% teamsArr.forEach(team => { %>
        <option value="<%= team %>"><%= team %></option>
      <% }) %>
    </select>
  </div>
  <% }; %>
  <button type="submit" class="btn btn-primary">Save changes</button>
</form>

<form class="mt-3 mb-3" method="POST" action="/api/users/makePicks/2">
  <% for(i=0; i < user.bullets; i++){ %>
  <div class="form-group">
    <label for="<%= `${user.name}-${i}` %>">Make your pick for bullet <%= `${i}` %></label>
    <select class="form-control" name="<%= `${user.name}-${i}` %>" id="<%= `${user.name}-${i}` %>">
      <% teamsArr.forEach(team => { %>
        <option value="<%= team %>"><%= team %></option>
      <% }) %>
    </select>
  </div>
  <% }; %>
  <button type="submit" class="btn btn-primary">Save changes</button>
</form>

你想在一个 findByIdAndUpdate 中使用 $push$set,这是不可能的,我更喜欢使用 findById()processsave() 所以试试吧

exports.makePicks = async (req, res, next) => {
  const picks = req.body;
  try {
    //implementation business logic
    let result = await User.findById(req.user._id)
    if(result.picks && result.picks.length > 0){
      result.picks.forEach(item =>{
        if([`week-${req.params.week}`] in item){
          item[`week-${req.params.week}`] = picks
        }
        else{
          result.picks.push({ [`week-${req.params.week}`] : picks })
        }
      })
    }
    else{
      result.picks.push({ [`week-${req.params.week}`] : picks })
    }

    await result.save()
    res.redirect('/api/dashboard');
  } catch (error) {
    console.log(error)
  }
}

注意:不要同时使用 callbackasync/await

exports.makePicks = async (req, res, next) => {
  const picks = req.body;
  const { week } = req.params;
  try {
   
    let result = await User.findById(req.user._id);
    const data = { [`week-${week}`]: picks };
    const allPicks = [...result.picks];
    
    if (allPicks.length > 0) {

      // Search index of peek
      const pickIndex = _.findIndex(allPicks, (pick) => {
        return Object.keys(pick)[0] == `week-${week}`;
      });

      // If found, update it
      if (pickIndex !== -1) {
        console.log(chalk.green("true"));
        allPicks[pickIndex] = data;
      }

      // Otherwise, push new pick
      else {
        console.log(chalk.red("false"));
        allPicks.push(data);
      }

    } else {
      allPicks.push(data);
      console.log(chalk.yellow('results.picks is empty'))
    }

    result.picks = allPicks;
    console.log('allPicks', allPicks);
    
    await result.save();
    res.redirect("/api/dashboard");
  } catch (error) {
    console.log(error);
  }
};