Ali Bahrami
Ali Bahrami

Reputation: 503

enforcing uniqueness in loopback4 model's properties

I started to run a simple hello world project using lb4. I created a basic mongodb datasource, and a repository and a simple model (username, password and id) for users with cli command provided by loopback. I also created a user controller, with a built in crud choice provided by loopback.
as you may know, this is a very basic setup but if anyone needs details, I will provide, just comment.
the problem is that, when I try to make new users using explorer, I encounter with duplicate same username models. means that:

{
"_id" : ObjectId("5def4581f7f9d508b0da2d4c"),
"username" : "string",
"password" : "string"
}

and:

{
"_id" : ObjectId("5def4584f7f9d508b0da2d4d"),
"username" : "string",
"password" : "string"
}

the client should enter unique username for signup. that's obvious.
how can I specify uniqueness of a property of a model in loopback 4 (without declaring it as id)?

Upvotes: 0

Views: 841

Answers (2)

Ali Bahrami
Ali Bahrami

Reputation: 503

Due to this issue on github, lb4 already checks for duplicates inside of its context using indexes and 11000 error code of mongoDB (I am talking about shopping example, not a simple lb4 app so BE AWARE! If you want you can implement uniqueness using description below). What I forgot to do was database migration πŸ±β€πŸ.
you can do database migration with this command:
npm run migrate
so the complete answer should be like this:
1- inside the model add this: (change uniqueEmail and email to property name you want to be unique)

@model({
    settings: {
        indexes: {
          uniqueEmail: {
            keys: {
              email: 1,
            },
            options: {
              unique: true,
            },
         },
    },
  },
})

2- check inside of the controller, the endpoint you want to check uniqueness, and add a try catch to catch error of uniqueness which came from your mongoDB datasource:

try {
  // In my case create the new user, but can be anything you want
  const savedUser = await this.userRepository.create(
    _.omit(newUserRequest, 'password'),
  );

  // do stuff and return

} catch (error) {
  // MongoError 11000 duplicate key
  if (error.code === 11000 && error.errmsg.includes('index: uniqueEmail')) {
    throw new HttpErrors.Conflict('Email value is already taken');
  } else {
    throw error;
  }
}

3- run npm run migrate

This answer now is a general answer which can be used for any property of any model. Hope this helps.

Upvotes: 1

Akif Hussain
Akif Hussain

Reputation: 365

So basically what i found out that Loopback4 has a property called name which a unique identifier for the authentication strategy ( for example : β€˜basic’, β€˜jwt’, etc). You can look into more detailed manner here AND here

You should change the username to name so as to fulfill your requirement. Because that's how it works in loopback4

Upvotes: 0

Related Questions