beforeSearch / afterSearch hook gone? (beforeCountSearch / afterCountSearch as well?)

Greetings, in Strapi 3.1.6 the following lifecycle hook was still triggered, which I used to create a type of “calculated field”, in the admin entity list view (!), i.e. something that is displayed in the pager view (!) as a value determined on-the-fly:

module.exports = {
    lifecycles: {
        async afterSearch(entries, params) {
            console.log("Hello I am the afterSearch hook!");
            /* Calculate something on the fly here, for example combine two fields in some algorithmic way */
        }
    }
}

However, as of 3.6.3, which is the next version I tried after 3.1.6, it seems like that hook is never called any more, at least not when normally paging through the pager.

If you hadn’t heard of the beforeSearch hook, I hadn’t either, until I found this article on strapi.io: Guide to Content Modelling in Strapi

In version 3.1.6, it works to display “calculated data” in the pager, i.e. i can create “virtual columns” that get their data in real time from other columns, or from the outside world even, or a mix of both. In 3.6.3, it shows empty fields only (as the fields in question don’t exist as a real database “cell”) (I have not tried any versions above 3.1.6 and below 3.6.3).

Is this a new caching scheme that avoids round-trips through hooks deliberately? The current admin interface is quite a bit faster and responsive than the 3.1.6 one but if the price is I can’t display the data that I want, I would prefer to turn off this “caching” for that entity type. Possible?

If the afterSearch hook has been renamed to something else, or there is a different, clean way to display on-the-fly calculated cells in the admin pager, LMK! Much appreciated.

System Information
  • Strapi Version: 3.6.3
  • Operating System: Ubuntu 16
  • Database: MongoDB 4.x
  • Node Version: 15.14
  • NPM Version: 7.16
  • Yarn Version: N/A

Ok replying to self, the models are documented here and it seems nothing has changed in the lifcycle hooks themselves.

But something has changed in respect to that the afterSearch hook is no longer triggered when browsing around in the content-manager url, example /admin/plugins/content-manager/collectionType/application::myitem.myitem

So I cannot use these hooks any more to “trick” Strapi into displaying fields that are calculated on the fly, in the pager / list view.

Are there any guidelines to override this behavior or bypass any “caching” that Strapi is doing now, that it wasn’t doing in v3.1.6? I am a bit lost…

Working fine in the test I just ran:

Path: api/article/models/article.js

module.exports = {
  lifecycles: {
    beforeCreate(...args) {
      console.log("beforeCreate");
    },
    afterCreate(...args) {
      console.log("afterCreate");
    },
    beforeUpdate(...args) {
      console.log("beforeUpdate");
    },
    afterUpdate(...args) {
      console.log("afterUpdate");
    },
    beforeDelete(...args) {
      console.log("beforeDelete");
    },
    afterDelete(...args) {
      console.log("afterDelete");
    },
    beforeFind(...args) {
      console.log("beforeFind");
    },
    afterFind(...args) {
      console.log("afterFind");
    },
    beforeFindOne(...args) {
      console.log("beforeFindOne");
    },
    afterFindOne(...args) {
      console.log("afterFindOne");
    },
    beforeCount(...args) {
      console.log("beforeCount");
    },
    afterCount(...args) {
      console.log("afterCount");
    },
    beforeSearch(...args) {
      console.log("beforeSearch");
    },
    afterSearch(...args) {
      console.log("afterSearch");
    },
    beforeCountSearch(...args) {
      console.log("beforeCountSearch");
    },
    afterCountSearch(...args) {
      console.log("afterCountSearch");
    },
  },
};

The lifecycles are mainly intended for the end-user APIs and Admin has it’s own internal API that may not entirely use the same queries that the end-users do.

In the v4 we plan to entirely split the two as in the v3 some things are shared.

Therein lies my problem. It used to be that all admin output was filtered through the lifecycle hooks. So “old” Strapi was fantastic to I give my client access to a “rough and ready” back-end so they can enter their data and push some buttons to stop and start some background processes that my application controls. I didn’t need to spend weeks to build a React user interface, at least not for the client, who can be inconvenienced and trusted with admin access.

Part of the rough and ready user interface were almost always “virtual” or “calculated” fields such as “myentity.profitability = myentity.gross_income - myentity.cost” which the client wants to see “at one glance” in a spreadsheet type view so he can sort and copy the data.

That view was – you guessed it – the admin list / pager view.

So it seems like that shortcut to client bliss is dead. Is there a new / undocumented / hacky way to still make the admin list view call all the hooks as it used to be in v3.1.6 (which is the last one I tested)?

Even if you named the correct file to patch, that would help me a lot, I would figure it out from there…

Cheers mate and thanks for a great system. Makes me look really good in front of my clients.

The easiest (and I say that with a bit of salt) would be to add the “hack” into the content-manager controller/services since that’s what’s being called.

Downside is those are generic so you have to read the incoming request and filter out and only perform your logic modification to the specific call/model.

I’m not super familiar with our frontend (admin) parts of the code-base in terms of modification but it should be able to be done via extensions (no npm-patch needed, but could be used if you wanted).

For the controller file, most likely here: strapi/collection-types.js at master · strapi/strapi · GitHub

And service file: strapi/content-types.js at master · strapi/strapi · GitHub

Doesn’t matter where you intercept to modify the response, controller might be easier.