Recursive include Sequelize?

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.


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(...)