Ignas Damunskis
Ignas Damunskis

Reputation: 1504

Express.js mongoose: TypeError Cannot set property of undefined

I created an UserSchema and added a method in which i try to set it's property name:

import mongoose, { Schema } from 'mongoose'

const UserSchema = new Schema({
  name: String
})

UserSchema.methods.setName = (name) => {
  this.name = name + '123'
}

exports default mongoose.model('User', UserSchema)

I imported the object and called the method from the controller I created:

import User from './User'

exports.signup = (request, response) => {
  const name = 'Ignas'

  const UserModel = new User
  UserModel.setName(name)

  ...
}

For some reason it throws me an error:

TypeError: Cannot set property "name" of undefined

How could this be undefined?

If I modify a method passing the object I could make it working as I want, but it looks dirty and incorrect since all I want to do is to change object´s property through it´s method..

// modified method of Schema
UserSchema.methods.setName = (User, name) => {
  User.name = name + '123'
}

// modified call from the controller
UserModel.setName(name)

Upvotes: 1

Views: 990

Answers (2)

Dez
Dez

Reputation: 5838

Arrow functions don't bind its own this. They use lexical this. Arrow functions lexically bind their context so this actually refers to the originating context. This is called lexical scoping. And what lexical scoping means:

Lexical scoping (sometimes known as static scoping ) is a convention used with many programming languages that sets the scope (range of functionality) of a variable so that it may only be called (referenced) from within the block of code in which it is defined.

You have more explanations about this issue in MDN for example.

At the end, what it happens is that it will look for this in all parent's context until it finds it, and in your case, because in the module there is not a definition of this anywhere, returns undefined.

Upvotes: 1

hoangdv
hoangdv

Reputation: 16127

You are using Arrow function syntax, this keyword with arrow function has some things mess.

Hotfix: Use old school function syntax

UserSchema.methods.setName = function(name) {
  this.name = name + '123'
}

Upvotes: 0

Related Questions