Search code examples
node.jsloopbackjs

Registering new users on loopbackjs application


I have already checked this question. But the answer doesn't quite match what I am looking for. Extend built-in User model to support more properties and behaviors in loopback

What I am trying to do: Register a new user on my test application. I just need to save the data to mysql database when I click register. Most of the examples on the loopback documentation to register new user, is from a boot script. And the example here does not save it to database - https://github.com/strongloop/loopback-example-user-management. This is more of a problem on why I am not able to save it to database and not so much on the register or user models. But the model userAccount extends from the User base model. So I am not sure if this works differently. I am still not completely familiar with Loopback framework, so any help is greatly appreciated. Thanks.

Background Using loopback 3.0 with NodeJS 8.1.0. Connector used - loopback-connector-mysql connected to MySQL database hosted on Azure.

Using POST /userAccounts (default API endpoint) created by loopback can connect to the database and save user. I am only having trouble with the remote method POST /register.

Problem I get a function not found error. Screenshot - Screenshot of error

/server/model.config

{
  "_meta": {
    "sources": [
      "loopback/common/models",
      "loopback/server/models",
      "../common/models",
      "./models"
    ],
    "mixins": [
      "loopback/common/mixins",
      "loopback/server/mixins",
      "../common/mixins",
      "./mixins"
    ]
  },
  "User": {
    "dataSource": "db",
    "public": false
  },
  "AccessToken": {
    "dataSource": "db",
    "public": false
  },
  "userCredential": {
    "dataSource": "db",
    "public": false
  },
  "userIdentity": {
    "dataSource": "db",
    "public": false
  },
  "ACL": {
    "dataSource": "db",
    "public": false
  },
  "RoleMapping": {
    "dataSource": "db",
    "public": false,
    "options": {
      "strictObjectIDCoercion": true
    }
  },
  "Role": {
    "dataSource": "db",
    "public": false
  },
  "userAccount": {
    "dataSource": "mysqlDB",
    "public": true,
    "options": {
      "remoting": {
        "sharedMethods": {
          "*": true
        }
      }
    }
  },
  "job": {
    "dataSource": "db",
    "public": true
  },
  "jobSeekerProfile": {
    "dataSource": "db",
    "public": true
  },
  "userRegister":{
    "dataSource":null,
    "public":false
  }
}

/server/models/userAccount.json

{
  "name": "userAccount",
  "base": "User",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "username": {
      "type": "string",
      "required": true
    },
    "password": {
      "type": "string",
      "required": true
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": {
    "register": {
      "accepts": {
        "arg": "profile",
        "type": "userRegister",
        "description": "User profile details",
        "required": true,
        "http": {
          "source": "body"
        }
      },
      "returns": {
        "arg": "result",
        "type": "object",
        "root": true,
        "description": "This method indicates user registration status."
      },
      "description": "Register new user",
      "http": {
        "verb": "post"
      }
    }
  }
}

/server/models/userAccount.js

'use strict';

module.exports = function(usersHR) {
  class userAccount {
    async register(userRegister, req, callback) {
      var today = new Date();
      var newUserAccount = new userAccount({
        username: userRegister.username,
        password: userRegister.password,
        joinDate: today.toUTCString(),
        lastLogin: today.toUTCString(),
        realm: 'jobseeker',
        email: userRegister.email,
      });
      userAccount.save(newUserAccount, function(err) {
        if (err) {
          console.log(err);
        } else {
          console.log('User registered');
        }
      });

      callback(null, 'Registered');
    }
  }

  var cUserAccount = new userAccount(usersHR);

  usersHR.register = function() {
    cUserAccount.register(...arguments);
  };
};

/common/models/userRegister.json

{
  "name": "userRegister",
  "properties": {
    "username": {
      "type": "string",
      "description" : "username of user"
    },
    "email":{
      "type":"string",
      "description":"email of user"
    },
    "password": {
      "type": "string",
      "description" : "password of user"
    },
    "realm":{
      "type":"string",
      "description":"realm of user"
    }
  },
  "hidden": [
    "id"
  ]
}

Solution

  • What I am trying to do: Register a new user on my test application. I just need to save the data to mysql database when I click register.

    The default User model allows $everyone to create a user model. This means the simplest act of creating a user is to post to /api/Users/create.

    Most of the examples on the loopback documentation to register new user, is from a boot script. And the example here does not save it to database - https://github.com/strongloop/loopback-example-user-management.

    That is because the connector is the in-memory connector, you can swap in any persistant datasource and the user would persist.

    This is more of a problem on why I am not able to save it to database and not so much on the register or user models. But the model userAccount extends from the User base model. So I am not sure if this works differently. I am still not completely familiar with Loopback framework, so any help is greatly appreciated. Thanks.

    To solve your error, you're calling the save method on userAccount (the class you create in the function), you probably want to call it on usersHR.

    Old:

    userAccount.save(newUserAccount, function(err) {
            if (err) {
              console.log(err);
            } else {
              console.log('User registered');
            }
          });
    

    New:

    usersHR.save(newUserAccount, function(err) {
            if (err) {
              console.log(err);
            } else {
              console.log('User registered');
            }
          });