Я хочу собрать данные с его дочерним элементом (еще один элемент, связанный с этим идентификатором продукта). У меня есть коллекция с этой схемой
// User Schema
const filtersSchema = mongoose.Schema({
filter_name:{
type: String,
required: true
},
filter_code:{
type: String,
required: true,
unique: true
},
bind_to: {
type: Schema.Types.ObjectId,
default: null
},
filter_status:{
type: Boolean,
default: true
},
created_on:{
type: Date,
default: Date.now
},
updated_on:{
type: Date,
default: Date.now
}
});
Если я введу в нее данные, значение bind_to по умолчаниюбудет нулевым, это означает, что его родитель.Если я отправлю bind_to ID родителя, это будет ObjectID.
Я хочу собрать такие данные, как это
[{
-- parent object --
children:[
{
-- child object --
},
{
-- child object --
}
]
}]
, если у нас более одного элемента, он пройдетцикл (forEach), но обратный вызов отправляется до завершения цикла forEach.Я знаю, что forEach является асинхронным, и запрос является синхронным.но вы не знаете, как это сделать!
вы можете увидеть модуль ниже
// Get Filters by Parent ID
module.exports.getFiltersByParentId = (pid, callback) => {
Filters.find({bind_to: pid}, callback);
}
//For getting the parent object and looping it to get its child objects
module.exports.getFilters = (callback, limit) => {
Filters.find({bind_to: null}, (err, filters) => {
if (err) {
console.log(err);
let obj = {status: false, error: err.errmsg};
callback(obj);
} else {
const resObj = [];
filters.forEach(async function (ele) {
await Filters.getFiltersByParentId(ele._id, (err, cfil) => {
if (err) {
let obj = {status: false, message: err.errmsg};
callback(obj);
} else {
console.log(ele, "Obj");
ele.children = cfil;
resObj.push(ele);
}
});
});
Promise.all(resObj).then(res => {
let obj = {status: true, data: res, message: "Filters found"};
callback(obj);
});
}
});
}
, но в этом случае объект результата будет пустым.Как я могу получить правильный объект со значениями, как указано выше?
Даже я пытался с этим методом
const resObj = [];
filters.map(function (ele) {
Filters.getFiltersByParentId(ele._id, (err, cfil) => {
if (err) {
let obj = {status: false, message: err.errmsg};
callback(obj);
} else {
console.log(ele, "Obj");
ele.children = cfil;
resObj.push(ele);
}
});
});
Promise.all(resObj).then(res => {
let obj = {status: true, data: res, message: "Filters found"};
callback(obj);
});
И это
Promise.all(filters.map(function (ele) {
Filters.getFiltersByParentId(ele._id, (err, cfil) => {
if (err) {
let obj = {status: false, message: err.errmsg};
callback(obj);
} else {
console.log(ele, "Obj");
ele.children = cfil;
resObj.push(ele);
}
});
})).then(res => {
let obj = {status: true, data: res, message: "Filters found"};
callback(obj);
});
Хорошо, теперь явозвращая обещание от getFiltersByParentId
module.exports.getFiltersByParentId = (pid, callback) => {
return new Promise(function(resolve, reject) {
Filters.find({bind_to: pid}, function (err, results) {
if (err) {
reject(err);
} else {
resolve(results);
}
})
});
}