DRg
DRg

Reputation: 23

Mongoose unique NanoID

const user = new mongoose.Schema(
  {
    nano_id: {
      type: String,
      required: true,
      default: () => nanoid(7),
      index: { unique: true },
    },
...
}

How to run again nanoid(7) if is not unique? (run automatically and not get any error in console)

Upvotes: 2

Views: 1230

Answers (2)

Jassar
Jassar

Reputation: 341

There are two ways to do this:

  1. Prevent the error from happening in the first place by searching for a document with a similar Nano ID, if a document exists, regenerate a new Nano ID using a recursive function.
const { customAlphabet } = require('nanoid');
const alphabet = '0123456789abcdefghijklmnopqrstuvwxyz';
const nanoid = customAlphabet(alphabet, 8);


// userRegistration controller or route...

  async function uniqueNanoId(query): Promise<string> {
    const nanoId = nanoid();
    const sameNanoId = await User.findOne({ nano_id:nanoId });
    if (sameNanoId) {
      return uniqueNanoId(query);
    }
    return nanoId;
  }

  const nanoId = await uniqueNanoId();
  const user = User.create({...userBody,nanoId});

//...
  1. Catch the error - as @cachius hinted - and regenerate the unique Nano ID accordingly (not tested). Catching a duplicate key has been discussed here

  2. Bonus: Ask yourself the question, do I really need both Default Mongoose IDs and Nano IDs? If not, then this is a simple solution.

// ...
_id: {
    type: String,
    default: () => nanoid(),
  },
// ...

Upvotes: 1

cachius
cachius

Reputation: 1906

The database will throw an error you have to catch and react to by generating the same record again with a newly generated nanoid.

Upvotes: 0

Related Questions