简体   繁体   中英

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)

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 .

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'
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM