How to use params in lifecycles?

System Information
  • Strapi Version: 3.4.4
  • Operating System:
  • Database:
  • Node Version:
  • NPM Version:
  • Yarn Version:

Hello, I have a product category (self reference) and product type (category belongs to many types ) as follows:

{
  "kind": "collectionType",
  "collectionName": "product_categories",
  "info": {
    "name": "Product Category",
    "description": ""
  },
  "options": {
    "increments": true,
    "timestamps": true,
    "draftAndPublish": true
  },
  "attributes": {
    "name": {
      "type": "string"
    },
    "slug": {
      "type": "uid"
    },
    "parentCategory": {
      "model": "product-category",
      "via": "childCategories"
    },
    "childCategories": {
      "collection": "product-category",
      "via": "parentCategory"
    },
    "productTypes": {
      "collection": "product-type",
      "via": "productCategory"
    }
  }
}

{
  "kind": "collectionType",
  "collectionName": "product_types",
  "info": {
    "name": "Product Type",
    "description": ""
  },
  "options": {
    "increments": true,
    "timestamps": true,
    "draftAndPublish": false
  },
  "attributes": {
    "name": {
      "type": "string"
    },
    "slug": {
      "type": "uid"
    },
    "products": {
      "collection": "product",
      "via": "productTypes"
    },
    "productCategory": {
      "via": "productTypes",
      "model": "product-category"
    }
  }
}

When I create or update a product category, I want to automatically asign all the same relatition with product type to its parents. For example, I have shirts category which belongs to both product types man and woman, then its parent category clothing also belongs to man and woman.

So I create a custom service function:

    findParents(params, populate) {
        // to find all parent categories id based on the current category slug / id
        let productCategory = strapi.services['product-category'].findOne(params, populate)

        console.log('productCategory:', JSON.stringify(productCategory))

        let result = []
        var parent = productCategory.parentCategory

        do {
            if (typeof parent.parentCategory === 'number') {
                result.push(parent.id)
                parent = strapi.services['product-category'].findOne({ id: parent.parentCategory })
            } else {
                result.push(parent.id)
                parent = parent.parentCategory
            }
        } while (parent)

        return result
    },

and then call the function in lifecycles:

lifecycles: {
        afterUpdate: async (result, params, data) => {
            console.log(params)
            if (data.productTypes && result.parentCategory) { 

                // if the current category is assigned types and has parents
                // find all parents and add the product types to them

                const parents = await strapi.services['product-category'].findParents({ id: params.id })
                console.log(parents)
                parents.map(parent => (parent.productTypes = data.productTypes))
            }

            console.log('data', JSON.stringify(data))
        },
    },

but the productCategory in the findParents is empty. Could you please give a little bit guidance?

It seems to work with the following code, but it might not be clean enough.

afterUpdate: async (result, params, data) => {

            if (data.productTypes && result.parentCategory) {
                let productCategory = await strapi.services['product-category'].findOne({ id: params.id })
                let result = []
                var parent = productCategory.parentCategory
                do {
                    if (typeof parent.parentCategory === 'number') {
                        result.push(parent.id)
                        parent = await strapi.services['product-category'].findOne({ id: parent.parentCategory })
                    } else {
                        result.push(parent.id)
                        parent = parent.parentCategory
                    }
                } while (parent)

                result.map(async id => {
                    let parent = await strapi.services['product-category'].findOne({ id: id })
                    let updatedTypes = []

                    data.productTypes.map(type => {
                        if (!JSON.stringify(parent.productTypes).includes(type.name)) {
                            updatedTypes.push(type)
                        }
                    })

                    await strapi.services['product-category'].update(
                        { id: id },
                        {
                            productTypes: updatedTypes,
                        },
                    )
                })
            }
        },