Search code examples
javascriptfeathersjs

FeathersJS: Creating a record inside a hook


I am new to FeathersJS and I am trying to do the following:

My app has two entities named Company and User. When someone registers a new company the name, email and a password for the owner are informed.

Then, after creating the record for the company in my companies table I need:

1) To retrieve the id of the new company;

2) Create an user with this id ad companyId, the name of the owner, the email of the owner and the given password.

Of course this should be done in a after insert hook for the companies service, but I am very confused about how to invoke the users service to perform this insert.

This is my companies.model.js file:

module.exports = function (app) {
  const sequelizeClient = app.get('sequelizeClient');
  const companies = sequelizeClient.define('companies', {
    company: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 100
    },
    cpfcnpj: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 25
    },
    owner: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 100
    },
    cpf: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 25
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 100
    },
    addr1: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 100
    },
    addr2: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 100
    },
    city: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 100
    },
    state: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 2
    },
    zip: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 10
    },
    phone: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 50
    }
  }, {
    hooks: {
      beforeCount(options) {
        options.raw = true;
      }
    }
  });

  companies.associate = function (models) {

  };

  return companies;
};

and this is my users.model.js:

module.exports = function (app) {
  const sequelizeClient = app.get('sequelizeClient');
  const users = sequelizeClient.define('users', {
    companyID: {
      type: DataTypes.INTEGER,
      allowNull false,
      size: 11
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      size: 100
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
      size: 100
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false
    },
    type: {
      type: DataTypes.STRING,
      allowNull: false,
      default: 'CL',
      size: 2
    }
  }, {
    hooks: {
      beforeCount(options) {
        options.raw = true;
      }
    }
  });

  users.associate = function (models) {

  };

  return users;
};

I understand that in my file companies.hooks.js I should have something like

module.exports = {

  before: {
    all: [],
    ...
  },

  after: {
    ...
    create: [ insertUser() ],
    ...
  },

  error: {
    ...
  }
};

but apart from that I don't really know how should I write my insertUser() function or where to put it. As I told you, I'm new with FeathersJS, this is my first day.

EDITED:

The first part of the question is answered. I used some console.log()s here and there and found out the object context passed to the hook has an object named result inside it when you are in an after hook, which is the case. Using this object now have the company id, the name and email of the owner.


Solution

  • It is all inside context.

    When you use a hook in FeatherJS, your hook function receives an object named context and this object has all you need.

    In an after hook we have context.result, an object with the result of the previous query. In an insert query, like in the question, context.result has all the inserted information, including the id of the inserted company.

    Besides, the context object contains a reference to the FeathersJS app object, which is the application being run, with all its services and hooks and everything. So, in order create the user, as required in the question, all you have to do is:

    Edit the file src/services/companies/companies.hooks.js and add, right in the beginning, after the imports, a function like this

    const createUser = function(context) {
      const userRecord = {
        companyID: context.result.id,
        name: context.result.owner,
        email: context.result.email,
        // Get all other information you need here
      };
      context.app.service('users').create(userRecord);
    };
    

    Register this hook right below in the same file

    module.exports = {
      before: {
        all: [authenticate('jwt')],
        find: [],
        get: [],
        create: [],
        update: [],
        patch: [],
        remove: []
      },
    
      after: {
        all: [],
        find: [],
        get: [],
        create: [ createUser ], // <<=== registering the hook
        update: [],
        patch: [],
        remove: []
      },
    
      error: {
        all: [],
        find: [],
        get: [],
        create: [],
        update: [],
        patch: [],
        remove: []
      }
    };
    

    And it is done! Every time you create a new company the after hook will be executed and a new user will be created in association with that company.

    Click here for more information on FeathersJS hooks.