documentation icon indicating copy to clipboard operation
documentation copied to clipboard

strapi.db is undefined in lifecycles.js file

Open larbish opened this issue 3 years ago • 12 comments

Bug report

Describe the bug

When trying to use lifecycles event with the database layer API as described here in the doc, strapi.db is undefined.

NB: I 'm using this syntaxe because I want to use the query state to share state between beforeXXX and afterXXX.

Steps to reproduce the behavior

  1. Create ./src/api/[api-name]/content-types/[content-type-name]/lifecycles.js
  2. Copy paste the code to register a subscriber through the db API (available here):
// registering a subscriber
strapi.db.lifecycles.subscribe({
  models: [], // optional;

  beforeCreate(event: Event) {
    const { data, where, select, populate } = event.params;

    event.state = 'doStuffAfterWards';
  },

  afterCreate(event: Event) {
    if (event.state === 'doStuffAfterWards') {
    }

    const { result, params } = event;

    // do something to the result
  },
});
  1. Launch strapi
  2. Note the Cannot read property 'lifecycles' of undefined error

Expected behavior

Working behavior as described in the doc

System

  • Node.js version: node:14-alpine docker image
  • Yarn version: 1.22.5
  • Strapi version: V4.0.2
  • Database: pgsql
  • Operating system: Linux Ubuntu 18.04

Additional context

In any other files, strapi.db exists

larbish avatar Dec 29 '21 10:12 larbish

Hello @derrickmehaffy, why did you move this issue in documentation ? Do i need to change something to make it works ?

larbish avatar Jan 04 '22 10:01 larbish

Hello @derrickmehaffy, why did you move this issue in documentation ? Do i need to change something to make it works ?

Because this isn't how lifecycles work, the subscription side of things shouldn't be done in this file, those are designed to be used elsewhere and TBH I have no idea where.

derrickmehaffy avatar Jan 04 '22 16:01 derrickmehaffy

Thanks for the answer. Is there another way to use state to share data between beforeXXX and afterXXX ?

larbish avatar Jan 04 '22 16:01 larbish

Thanks for the answer. Is there another way to use state to share data between beforeXXX and afterXXX ?

state is a feature that's coming, it's documented but the code for it isn't actually there yet.

@alexandrebodin / @JabStrapi any ETA on the lifecycles state from the devexp squad?

derrickmehaffy avatar Jan 04 '22 16:01 derrickmehaffy

So, this documentation does not work. How do we achieve this same result?

samura avatar Jan 31 '22 16:01 samura

There is a pull request to add this feature: https://github.com/strapi/strapi/pull/12203

derrickmehaffy avatar Jan 31 '22 21:01 derrickmehaffy

any update on this? I walked into this issue when following the example in the docs.

gvr37leo avatar Mar 13 '22 16:03 gvr37leo

I faced the same issue following the documentation. Did anyone find a work around ? Any help is welcome...

anthoninCL avatar Mar 31 '22 13:03 anthoninCL

Hi, it looks like this issue was resolved with an update to the main Strapi code in May. I will close it for now, but please comment or open a new issue if there are additional problems.

stb13579 avatar Sep 05 '22 08:09 stb13579

Node.js version: node:16.17.0 Yarn version: 1.22.19 Strapi version: V4.3.6 Database: pgsql

Hi,I find this issue still exists.It shows "Cannot read property 'lifecycles' of undefined error" after i flowing the documentation.When I print strapi.db in console,it shows undefined.

sparrowhuang avatar Sep 13 '22 02:09 sparrowhuang

Hi @sparrowhuang Could you share the code that is not working and a link to the documentation that you are using?

stb13579 avatar Sep 13 '22 04:09 stb13579

Dear Shaun Brown,

console.log("strapi.db",strapi.db)//undefined

strapi.db.lifecycles.subscribe({
    models: [], // optional;
  
    beforeCreate(event) {
      const { data, where, select, populate } = event.params;
  
     
    },
  
    afterCreate(event) {
    
  
      const { result, params } = event;
  
      // do something to the result
    },
});//throw Error("Cannot read properties of undefined (reading 'lifecycles')")

It seems like that the database layer API is not work.

Link:https://docs.strapi.io/developer-docs/latest/development/backend-customization/models.html#declarative-and-programmatic-usage

sparrowhuang avatar Sep 13 '22 05:09 sparrowhuang

I put it in the bootstrap function located in ./src/index.js and it worked.

module.exports = {
  register() {
    // some sync code
  },
  bootstrap({strapi}) {
         // generic subscribe for generic handling
      strapi.db.lifecycles.subscribe((event) => {});
  },
  destroy() {
    // some sync code
  }
};

Robright20 avatar Oct 24 '22 07:10 Robright20

But this way is still wrong.

// ./src/api/[api-name]/content-types/[api-name]/lifecycles.js
// registering a subscriber
strapi.db.lifecycles.subscribe({
  models: [], // optional;

  beforeCreate(event) {
    const { data, where, select, populate } = event.params;

    event.state = 'doStuffAfterWards';
  },

  afterCreate(event) {
    if (event.state === 'doStuffAfterWards') {
    }

    const { result, params } = event;

    // do something to the result
  },
});

sparrowhuang avatar Oct 24 '22 09:10 sparrowhuang

Hello @derrickmehaffy, why did you move this issue in documentation ? Do i need to change something to make it works ?

Because this isn't how lifecycles work, the subscription side of things shouldn't be done in this file, those are designed to be used elsewhere and TBH I have no idea where.

according to this, It looks like the subscriptions doesn't belong to that file. So I prefer to use the module.exports for the lifecycles and if I have to use the subscriptions, I would go with the bootstrap functions

Robright20 avatar Oct 24 '22 09:10 Robright20

the subscribe option should be use elsewhere in your codebase not within the lifecycles (this isn't really clear in the docs page)

derrickmehaffy avatar Oct 28 '22 17:10 derrickmehaffy

where in the code?

gvr37leo avatar Oct 28 '22 20:10 gvr37leo

where in the code?

Quite literally anywhere but inside the lifecycles file. It's used as a way to dynamically hook into the lifecycles, outside of the lifecycles.

derrickmehaffy avatar Oct 30 '22 15:10 derrickmehaffy

Hi, I'm closing this issue, but will mention it in #1906 so we can keep track of it. We'll improve the lifecycles documentation with the v5 documentation coming next year.

pwizla avatar Dec 04 '23 10:12 pwizla