2017-06-12 13 views
1

内部IはStorageと呼ばれる他のdocumentを基準ObjectIdの配列として定義documentUsersstorageとの特性を有します。私は特定のユーザーを取得しようとしているし、配列内のストレージ情報を返します。マングースfindOneループ

これは私のコードです:

module.exports.storageDetail = function(req, res) { 
     User.findOne({'userId': req.user.userId}, 'storages').then(function(data){ 
     var storageArray = []; 

     data.storages.forEach(function(record){ 
      Storage.findOne({_id: record}, function(err, storage){ 
      storageArray.push(storage); 
      }); 
     }); 

     return Promise.all(storageArray); 
     }).then(function(storageList){ 
     res.render('storage_template', { 
      storage: storageList 
     }); 
     console.log(storageList); 
     }); 
} 

しかし、実行後、storageListは空の配列です。

私はnode.jsの初心者です。詳細を提供する必要があるかどうか教えてください。

答えて

1

ここで重要な点は、約束を返すために.exec()にする必要があることです。これがあなたの試行が失敗した理由です。しかし、構文的にもより良いアプローチがあります。

代わり.map()を使用すると約束

User.findOne({'userId': req.user.userId}, 'storages').then(function(data){ 
    var storageArray = data.storages.map(function(id) { 
    return Storage.findOne({_id: id }).exec() 
    }); 
    return Promise.all(storageArray); 
}).then(function(storageList){ 
    res.render('storage_template', { 
    storage: storageList 
    }); 
    console.log(storageList); 
}); 

またはその代わりの方法は、配列を返すと、オペレータはあなたが一致するように、物事の配列を指定することができます.find()$inを使う返すように.exec()を呼び出します。

User.findOne({'userId': req.user.userId}, 'storages').then(function(data){ 
    return Storage.find({ "_id": { "$in": data.storages } }).exec(); 
}).then(function(storageList){ 
    res.render('storage_template', { 
    storage: storageList 
    }); 
    console.log(storageList); 
}); 

基本的には、代わりに単純に使用できるように見えます。.populate()

User.findOne({'userId': req.user.userId}, 'storages') 
    .populate('storages') 
    .then(function(data) { 
    res.render('storage_template', { 
     storage: data.storages 
    }); 
    console.log(data.storages); 
    }); 

実際にStorageモデルへの参照として定義されているかどうかは不明です。

また、マングースのドキュメントのQueries are not Promisesを参照してください。

+0

はあなたのようなstorages

を申請refを追加しましたあなたのUserモデルで最初に確認してください。この.populate()を使用するため、この1

module.exports.storageDetail = function(req, res) { User.findOne({'userId': req.user.userId}, 'storages') .populate('storages') .exec(function (err, storageList) { if (err) return handleError(err); console.log(storageList); res.render('storage_template', { storage: storageList }); }); } 

を試すことができます!最初のものをES5でどのように使うことができますか教えてください。 – Valip

+0

@Valip太い矢印の構文を通常の関数に置き換えました。ここでの主なポイントはPromiseを得るための '.exec()'です。 –

0

//はNPMあなたがマングースを使用している場合、あなたはStorageコレクションからあなたstorages情報の詳細を取得するために.populate()を使用することができますlodash

const _ = require('lodash'); 
module.exports.storageDetail = function(req, res) { 
    User.findOne({'userId': req.user.userId}, 'storages').then(function(data){ 
    var storageArray = []; 
    let queries = _.map(data.storages, (record)=>{ 
    return Storage.findOne({_id: record}, function(err, storage){ 
     storageArray.push(storage); 
     }); 
}) 

    return Promise.all(queries); 
    }).then(function(storageList){ 
    res.render('storage_template', { 
     storage: storageList 
    }); 
    console.log(storageList); 
    }); 
} 
1

をインストールします。どちらのソリューションは素晴らしい作業している

storages: [{ type: Schema.Types.ObjectId, ref: 'Storage' }]