Fedoranimus Fedoranimus - 4 months ago 75
Node.js Question

Chaining ES6 Promises in Mongoose with Typescript

I'm attempting to chain ES6 promises with Mongoose 4.5.4

public static signup(req: express.Request, res: express.Response) {
UserModel.findOne({ email: req.body.email }).exec()
.then(existingUser => {
if(existingUser) {
return res.send({ message: 'Email is in use' });
}

return UserModel.create({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password
});
})
.then(user => {
return res.send({ token: AuthUtils.createJWT(user)});
})
.catch(err => {
console.log(err);
});
}


However, Typescript is throwing the following error when I attempt to
return UserModel.create(...)
:

Argument of type '(existingUser: IUser & _Model<IUser> & EventEmitter) => Response | MongoosePromise<IUser & _Model...' is not assignable to parameter of type '(...args: (IUser & _Model<IUser> & EventEmitter)[]) => void | (IUser & _Model<IUser> & EventEmitt...'.
Type 'Response | MongoosePromise<IUser & _Model<IUser> & EventEmitter>' is not assignable to type 'void | (IUser & _Model<IUser> & EventEmitter) | PromiseLike<IUser & _Model<IUser> & EventEmitter>'.
Type 'Response' is not assignable to type 'void | (IUser & _Model<IUser> & EventEmitter) | PromiseLike<IUser & _Model<IUser> & EventEmitter>'.
Type 'Response' is not assignable to type 'PromiseLike<IUser & _Model<IUser> & EventEmitter>'.
Property 'then' is missing in type 'Response'.


.create()
returns a Promise, so I cannot see how this would be an issue.

Any help would be appreciated.

Answer

Add control flow to the existing user by using a existing flag on the promise's response. Example:

public static signup(req: express.Request, res: express.Response) {
      UserModel.findOne({ email: req.body.email }).exec()
      .then(existingUser => {
          if(existingUser) {
              return Promise.resolve({
                user: existing,
                existing: true
              });
          }
          return UserModel.create({
              firstName: req.body.firstName,
              lastName: req.body.lastName,
              email: req.body.email,
              password: req.body.password
          }).then((user) => {
            return Promise.resolve({
              existing: false,
              user: user
            });
          });
      })
      .then(response => {
        if (response.existing) {
          return res.send({ message: `Email ${response.user.email} is in use` });
        } else return res.send({ token: AuthUtils.createJWT(response.user)});
      })
      .catch(err => {
          console.log(err);
      });
  }
Comments