Using method defined in the constructor after querying document from database

Tags: , ,



UPDATE ( ANOTHER SOLUTION)

What I was looking for, I found out later, was the possibility of making the method static. Then I can apply the method independently from the class.


Supposing I defined the following contructor:

export const User = class User {
  constructor(
    email,
    password,
    name,
  ) {
    this.name = name;
    this.email = email;
    this.password = password;        
  }

  async save() {
    const db = getDb("messages");
    const result = await db.collection("users").insertOne(this);
    return {
      ...result.ops[0],
      _id: result.ops[0]._id.toString(),
    };
  }

  newMethod (_id) {
    //Do something with User
  }
};

After fetching the User via CRUD operation (ex, findOne), I get an object back, the one I can’t apply the newMethod defined in the constructor. It seems the result from my query is some kind of read-only that doesn’t inherit the methods from the constructor. How to solve that?

Answer

You’re explicitly returning a plain object:

return {
  ...result.ops[0],
  _id: result.ops[0]._id.toString(),
};

That object isn’t connected in any way to the User instance that you called save on.

If you want to remember the information in result on the User instance, you’d assign it to properties on this. (And then you wouldn’t need the _id parameter on newMethod.)

For instance, to blindly copy all own, enumerable properties from result.ops[0] to this, you could use Object.assign:

async save() {
    const db = getDb("messages");
    const result = await db.collection("users").insertOne(this);
    Object.assign(this, result.ops[0]);         // Copies _id as-is
    this._id = result.ops[0]._id.toString();    // If you want it as a string instead
}

Then you could use this._id in newMethod.

(Alternatively you could assign specific properties.)



Source: stackoverflow