I have category that can have child categories
And when I'm doing findAll I want to include all of those nested, but I don't know the depth.
var includeCondition = {
include: [
{
model: models.categories,
as:'subcategory', nested: true
}]
};
models.categories.findAll(includeCondition)
.then(function (categories) {
resolve(categories);
})
.catch(function (err) {
reject(err);
})
});
The result brings me only one level nested include.
[
{
dataValues:{
},
subcategory:{
model:{
dataValues:{
}
// no subcategory here
}
}
}
]
Can I somehow make sequalize include those nested subcategories ?
This is ihoryam's answer adapted to ES6, using async/await
, arrow functions () =>
and Sequelize ORM to fetch the data, and not using Lodash.
const getSubCategoriesRecursive = async (category) => {
let subCategories = await models.category.findAll({
where: {
parentId: category.id
},
raw : true
});
if (subCategories.length > 0) {
const promises = [];
subCategories.forEach(category => {
promises.push(getSubCategoriesRecursive(category));
});
category['subCategories'] = await Promise.all(promises);
}
else category['subCategories'] = [];
return category;
};
Async functions returning promises, you do not need to precise return new promise(...)
There are few solutions if found for this first one is more complicated but will give better performance:
This one is about implementing hierarchical data structure in MySQL I like the guide here
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
The one that is named The Nested Set Model.
The second solution that I actually implemented by myself is recursive expanding, this one uses lots of mysql requests and I believe can be improved, but it's a fast one and works well. The thing is to use for each category function like this
var expandSubcategories = function (category) {
return new promise(function (resolve, reject) {
category.getSubcategories().then(function (subcategories) {
//if has subcategories expand recursively inner subcategories
if (subcategories && subcategories.length > 0) {
var expandPromises = [];
_.each(subcategories, function (subcategory) {
expandPromises.push(expandSubcategories(subcategory));
});
promise.all(expandPromises).then(function (expandedCategories) {
category.subcategories = [];
_.each(expandedCategories, function (expandedCategory) {
category.subcategories.push(expandedCategory);
}, this);
//return self with expanded inner
resolve(category);
});
} else {
//if has no subcategories return self
resolve(category);
}
});
});
};
So it's going through the categories and expanding them recursively.
Maybe this will help someone as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With