Why is the reference not being saved along with the rest of the data?

Viewed 93

I am new with MongoDB "relations" and I am trying to save data to a MongoDB database. There are two models, one model is the user and the other model is the authentication data. The data is saved correctly.

import { Schema, model } from 'mongoose'

const stringRequired = {
  type: String,
  trim: true,
  required: true
}

const stringUnique = {
  ...stringRequired,
  unique: true
}

const UserSchema = new Schema({
  name: stringRequired,
  username: stringUnique,
  email: stringUnique,
}, { timestamps: true });

const AuthSchema = new Schema({
  email: { type: Schema.Types.ObjectId, ref: 'User' },
  salt: stringRequired,
  hash: stringRequired,
}, { timestamps: true })

export const userModel = model('User', UserSchema)
export const authModel = model('Auth', AuthSchema)

As you can see, one of the models is referenced by another. The email field has a reference to the user, email being the id that I want to use for authentication. But for some reason, when I save the documents, all the data is sent except the reference.

This is my controller, which as you can see, abstracts the user and the authentication to carry out the business logic and then save it in the database separately.

function add(body: any) {
    return new Promise((resolve, reject) => {
      if (!body) {
        const error = new Error('No body on the request')
        reject(error)
      } else {
        const user = {
            username: body.username,
            email: body.email,
            name: body.name
        }

        const saltRouds = 10
        const salt = bcrypt.genSaltSync(saltRouds)
        const hash = bcrypt.hashSync(body.password, salt)
        const auth = { salt, hash }

        store.add(userModel, user)
        store.add(authModel, auth)
        resolve('User created')
      }
    })
  }

This is the store.add function.

async function add (collection: any, data: any) {
  return await collection.create(data)
}

Note this code is writhed with Typescript.

1 Answers

You're missing the reference key when creating the Auth instance. The "foreign key" in MongoDB is the id of a document that has type Schema.Types.ObjectId and can be accessed with document._id.

So your code should look like:

const auth = { salt, hash };

const user = store.add(userModel, user);
auth.email = user._id;

store.add(authModel, auth);

Be aware that your store.add() function is an async function and you should wait for it's result like @jfriend00 said in the comments.

You can achieve that by making add() also an async funtion and doing:

const auth = { salt, hash };

const user = await store.add(userModel, user);
auth.email = user._id;

await store.add(authModel, auth);

or using the Promise approach by chaining .then(). You can read more about it here.

Related