2017-05-14 11 views
1

私はnode express mongoose/mongoなどを使用して安らかなAPIを構築しています。特定のユーザーの後ろにいるユーザーの配列を出力しようとしています。ここにスキーマがあります。es6 mongoose入れ子findById約束

var UserSchema = new mongoose.Schema({ 
    username: {type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true}, 
    email: {type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/\[email protected]\S+\.\S+/, 'is invalid'], index: true}, 
    bio: String, 
    image: String, 
    following: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }] 
}, {timestamps: true}); 

したがって、すべてのユーザーには、配列内のユーザーの配列が 'following'キーで配列されています。私はそのリストを出力しようとしています。まず最初に自分のidを使ってユーザーレコードを探し、この配列をマッピングして、この現在のユーザーのフォローしているユーザーを探します。

router.get('/users/friends', auth.required, function(req, res, next) { 
    var limit = 20; 
    var offset = 0; 

    if(typeof req.query.limit !== 'undefined'){ 
    limit = req.query.limit; 
    } 

    if(typeof req.query.offset !== 'undefined'){ 
    offset = req.query.offset; 
    } 

    User.findById(req.payload.id) 
    .then(function(user){ 
    if (!user) { return res.sendStatus(401); } 

    return res.json({ 
     users: user.following.map(function(username){ 
     User.findById(username) 
      .then(function(userlist){ 
      console.log('userlist:',userlist.username); 
      return userlist.username; 
      }) 
      .catch(next) 
     }) 
    }) 
    }) 
    .catch(next); 
}); 

さて、このコードではconsole.logはJSコンソールで正しいデータを出力しますが、私はクライアントにこれを実現する方法を見つけるように見えることはできません。これまでのところ、私の努力はクライアントに「ヌル」値をもたらします。レコードの正しい量ですが、null値のみです。任意のアイデアをどのようにこれを修正するには?

以下のアドバイスを受けた後、私のコードを改訂しました。今では、クライアントへの最初のレコードを取得するために管理しますが、その後

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Can't set headers after they are sent. Blockquote

router.get('/users/friends', auth.required, function(req, res, next) { 
    var limit = 20; 
    var offset = 0; 

    if (typeof req.query.limit !== 'undefined') { 
     limit = req.query.limit; 
    } 

    if (typeof req.query.offset !== 'undefined') { 
     offset = req.query.offset; 
    } 


    User.findById(req.payload.id) 

     .then(function(user) { 
      if (!user) { 
       return res.sendStatus(401); 
      } 
      Promise.all(
       user.following 
      ).then(function(userarray) { 
       console.log(userarray); 
       userarray.forEach(function(userid) { 
        Promise.all([ 
         User.find({ 
          _id: { 
           $in: userid 
          } 
         }) 
         .limit(Number(limit)) 
         .skip(Number(offset)) 
         .populate('author') 
         .exec() 
        ]).then(function(results) { 
         userdetails = results[0]; 
         var userdetailsCount = results[1]; 

         return res.json({ 
          userdetails: userdetails.map(function(userdetail){ 
          return userdetail; 
          }) 
         }); 
        }) 
       }) 
      }) 
     }) 
     .catch(next); 
}); 

答えて

1

でエラーアウトはあなたの問題セクションは次のとおりです。

return res.json({ 
    users: user.following.map(function(username){ 
    User.findById(username) 
     .then(function(userlist){ 
     console.log('userlist:',userlist.username); 
     return userlist.username; 
     }) 
     .catch(next) 
    }) 
}) 

ビットUser.findById(username)は約束を返します。しかし、あなたはその約束を待っているわけではありません。私はあなたがuserlist.usernameをコンソールに記録して返し、その約束に従ったthen関数が、のリストを返すことを意味するはずです。しかし、そうではありません。あなたのmap関数は、約束事の配列を返しています。

BluebirdのPromise.maphttp://bluebirdjs.com/docs/api/promise.map.htmlのような機能があります(または、約束事の配列を扱うために、同様の機能を探してください)。

+0

お返事ありがとうございます。私はこのソリューションにes6 Promisesを組み込もうとしました。それはまだ働いていない。私の改訂コードの考え? – zookeemedia