Nodejs Promise TypeError: Cannot read property 'then' of undefined

11,751

You should wrap the whole User.findOne() call in a Promise, like so:

function create(data) {
  return new Promise((resolve, reject) => {
    User.findOne({ email: data.email })
      .exec((err, doc) => {
        if (err) return reject(err)
        if (doc) return reject(new Error('This email is already exists. Please enter another email.'))
        const user = new User(data)
        user.save((err) => {
          if (err) return reject(err)
          resolve()
        })
      })
  })
}

You also need to resolve the promise, otherwise the callbacks in your UserCtrl.then() calls will never be called. I also added error handling in case something goes wrong with saving a new User to the database.

Share:
11,751
tts
Author by

tts

Updated on June 04, 2022

Comments

  • tts
    tts almost 2 years

    I got error when i try to access function of controller in my route. I used mongoose,express.

    error:

    TypeError: Cannot read property 'then' of undefined at /private/var/www/html/sms/server/routes/user.routes.js:70:9 at Layer.handle [as handle_request] (/private/var/www/html/sms/node_modules/express/lib/router/layer.js:95:5) at next (/private/var/www/html/sms/node_modules/express/lib/router/route.js:137:13) at Route.dispatch (/private/var/www/html/sms/node_modules/express/lib/router/route.js:112:3) at Layer.handle [as handle_request] (/private/var/www/html/sms/node_modules/express/lib/router/layer.js:95:5) at /private/var/www/html/sms/node_modules/express/lib/router/index.js:281:22 at Function.process_params (/private/var/www/html/sms/node_modules/express/lib/router/index.js:335:12) at next (/private/var/www/html/sms/node_modules/express/lib/router/index.js:275:10) at Function.handle (/private/var/www/html/sms/node_modules/express/lib/router/index.js:174:3) at router (/private/var/www/html/sms/node_modules/express/lib/router/index.js:47:12) at Layer.handle [as handle_request] (/private/var/www/html/sms/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/private/var/www/html/sms/node_modules/express/lib/router/index.js:317:13) at /private/var/www/html/sms/node_modules/express/lib/router/index.js:284:7 at Function.process_params (/private/var/www/html/sms/node_modules/express/lib/router/index.js:335:12) at next (/private/var/www/html/sms/node_modules/express/lib/router/index.js:275:10) at /private/var/www/html/sms/server.js:65:3 POST /api/user/create 500 27.274 ms - 16 (node:11300) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: This email is already exists. Please enter another email. (node:11300) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

    here is my code:-

    user.cont.js

    function create(data) {
      User.findOne({ email: data.email })
        .exec((err, doc) => {
          if (err) {
            return new Promise((resolve, reject) => {
              return reject(err);
            })
          } else {
            if (doc) {
              return new Promise((resolve, reject) => {
                return reject(new Error('This email is already exists. Please enter another email.'));
              })
            } else {
              const user = new User(data);
              return user.save()
            }
          }
    
        })
    
    }
    
    
    export default { getUsers, create };
    

    user.route.js

    router.post('/create', (req, res, next) => {
            UserCtrl.create(req.body)
                .then(savedUser => res.json(savedUser)) . // here error is generated
                .catch(e => next(e));
        });
    
    • Seb D.
      Seb D. over 6 years
      You're missing a return in your create function.
  • Jaromanda X
    Jaromanda X over 6 years
    of course, in current versions of Mongoose, .findOne returns a Promise, so you can avoid this promise constructor anti-pattern