Strapi create new User (users-permissions plugin), lifecycles

Hello,

I am playing around with the new strapi, (v4) and i am trying to figure out how to perform another operation while a new user is created , such as creating a userAccount bounded to a user. Either via the /register route either via the admin /plugin::users-permissions.user.

Ive read the documentation and i proceeded with creating a new lifecycle.jsfile under the/extensions/users-permissions/content-types/user` directory.

Ive placed the following code module.exports = {
beforeCreate(event) {
console.log(‘before create’ + event);
},
afterCreate(event) {
console.log(‘after create’ + event);
// do something to the result;
},
};
and I don't seem to be able to make it work ? Ive place the same code, in a newly content-type i created and it seems to work fine, but in the user-permissions, it simply does not work.
Anyone knows how to tackle this?

Thanks in advance.

System Information
  • Strapi Version: 4.0.0
  • Operating System: Win 10
  • Database: .
  • Node Version: v14.17.0
  • NPM Version: 6.14.13
  • Yarn Version:

3 Likes

I’m also facing the same issue.

2 Likes

In v4 you can use strapi.db.lifecycles.subscribe to register lifecycle methods for any model. This is especially handy when you want to register lifecycle methods of plugin models. No more need to do some funky extensions stuff.

You can just place this in your bootstrap function.

strapi.db.lifecycles.subscribe({
  models: ['plugin::users-permissions.user'],
  async afterCreate(event) {
    // afterCreate lifeclcyle
  },
  async beforeCreate(event) {
    // beforeCreate lifeclcyle
  },
});
7 Likes

this example is great. Do you know how to change the email template for reset password and email verification? I have been trying but no luck so far.

Answer please. Do I understand correctly that when processing related collections, database mechanisms are used, and in fact there are no calls to strapi methods for the dependent collection? As a result lifecycle hooks don’t work. Example: calling /api/dependent_collection invokes the lifecycle hook beforeFindMany on dependent_collection, but calling /api/main_collection?populate=* does not invokes the lifecycle hook beforeFindMany being called on dependent_collection. Relationship main with dependent
belongs to many.

Hi

for me worked this solutions:

in folder src/extensions/users-permissions/content-types/user creat two files
index.js and lifecycles.js

// src/extensions/users-permissions/content-types/user/lifecycles.js
module.exports = {
    afterCreate(event) {
        console.log('afterCreate');
    },
    afterUpdate(event) {
        console.log('afterUpdate');
    }
}
// src/extensions/users-permissions/content-types/user/index.js
const schema = require('./schema.json');
const lifecycles = require('./lifecycles.js');

module.exports = {
    schema,
    lifecycles
}

and then in file src/extensions/users-permissions/strapi-server.js registered new user

// src/extensions/users-permissions/strapi-server.js
const user = require('./content-types/user');

module.exports = (plugin) => {    

    //...

    plugin.contentTypes.user = user;

    //...

    return plugin;
}


13 Likes

Hi @Robert_Hlavica,

Your solution works wonderfully, thank you very much!
Although I think it’s important to not that it only works with the Query Engine API, but not with the Entity Service API.

This worked for me, how do i now attach this new user as reference filed to another content type ?

hi this worked thanks, can you let me know how do i now attach this user that was created as a reference field to another content type? Do i need to create an extension or possible to do it here. can i get a ID of the user ? and append it to a multi reference field in another table.

It’s a pity is that strapi doesn’t provide an easy, out-of-the-box way to use lifecycle hook functions on user data. The DB lifecycle workaround seems to be the only option, here are some more hints to that: How can I create user lifecycle hooks in v4? - #3 by kieranlangton

This worked for me too Thank @Robert_Hlavica

This works for me too. Thanks

Hi @Robert_Hlavica your solution worked for me as well.

I’m sharing here how I managed to benefit from afterCreate lifecycle hook to create a related entry, on a different content-type, upon user cretion. Even using the high level entityService class:

// src/extensions/users-permissions/content-types/user/lifecycles.js
module.exports = {
    // Creates an associated user-detail entry upon user account creation
    afterCreate(event) {
        strapi.entityService.create('api::user-detail.user-detail', {
            data: {
               nick: event.result.username,
               users_permissions_user: event.result.id,
               // This enforces user-detail as published, instead of just a draft
               // https://forum.strapi.io/t/creating-entry-from-controller-goes-to-draft/22501/2
               publishedAt: new Date().getTime()
           },
        });
    }
}

beforeCreate doesnt seem to work with the suggested lifecycles file by Robert.

Ahh so as an FYI for anyone. The input validation will run before the ‘beforeCreate’ runs. So if you want to set defaults like ‘username’, you still need to pass something a username because it is required and then replace it in the before create.

You must use this

Go to src/index.js

"use strict";

const { newRegister } = require("../utils/sendMail");

module.exports = {
  /**
   * An asynchronous register function that runs before
   * your application is initialized.
   *
   * This gives you an opportunity to extend code.
   */
  register(/*{ strapi }*/) {},

  /**
   * An asynchronous bootstrap function that runs before
   * your application gets started.
   *
   * This gives you an opportunity to set up your data model,
   * run jobs, or perform some special logic.
   */
  // bootstrap(/*{ strapi }*/) {},

  async bootstrap({ strapi }) {
    strapi.db.lifecycles.subscribe({
      models: ["plugin::users-permissions.user"],
      async afterCreate(event) {
        // your code here
    });
  },
};

2 Likes

Its works, thanks