2017-09-26 15 views
1

私はmongoDBを持つNode.js APIを持っています。ユーザーを作成し、パスワードをハッシュする必要があるルートがあります。このためには、bcryptjsパッケージを使用します。Node.js Mongoose Promiseが失われる

ルートは次のようになります。

router.route('/user') 

    .post(function(req, res) { 
     if(req.body.password === req.body.passwordConfirm) { 
      userManager.addUser(req.body) 
       .then(function(response) { // waiting for the result of the mongoDB save 
        res.send({data:response}); 
       }); 
     } else { 
      res.send({err:'passwords do not match'}); 
     } 
    }) 

とuserManager.addUSer:と言われます " 'それから' 未定義のプロパティを読み取ることができません"、:

this.addUser = function(userobject) { 
    bcrypt.genSalt(10, function(err, salt) { // generate a salt 
     if(err !== null) { 
      console.log(err); 
     } else { 
      bcrypt.hash(userobject.password_hash, salt, function(err, hash) { // hash pw 
       if(err !== null) { 
        console.log(err); 
       else { 
        userobject.password_hash = hash; // store hash in user obj 
        var user = new User(userobject); 
        return user.save().catch(function(err){ // save user in mongoDB 
         console.log(err); 
        }); 
       } 
      }); 
     } 
    }); 
}; 

私はというエラーを取得します私はaddUserから約束を受けていない。私は見て、bcryptjsは悲しいことに約束を使わないが、mongooseはそうする。 (この追加:

var mongoose = require('mongoose').Promise = Promise; 

は役立ちませんでしたが)

私は拒否し、解決すると約束して機能をラップしようとしたが、それは、このエラーを与える:「例外TypeError:約束のリゾルバ未定義のは関数ではありません"

mongooseのsave()関数がポストルートの.then()に返されるという約束をどのように取得できますか?私は2つのbcrypt関数の前に戻り値を追加しようとしましたが、どちらもうまくいきませんでした..

どのような提案も大歓迎です!

+0

あなたは 'this.addUser'というPromiseフォームを返しません。 –

+1

をクリアするには、あなたは 'this.addUser'から** anything **を返さないでください –

+0

@Jaromanda Xはい私は今、私は約束を新しくしています。私は約束をサポートしていないAPIによって迷っていると思います.. –

答えて

1

addUser関数neversは、呼び出し側に約束を返します。 bcrypt.hashコールバック関数からreturnを実行していますが、これはaddUserの戻り値とは関係ありません。

addUserは(***コメントを参照してください)あなたがnew Promiseをやって立ち往生しているので、このようなものをいくつかの非約束対応のAPIを使用するために持っているように見えます:

this.addUser = function(userobject) { 
    return new Promise(function(resolve, reject) { // *** 
     bcrypt.genSalt(10, function(err, salt) { // generate a salt 
      if(err !== null) { 
       reject(err);      // *** 
      } else { 
       bcrypt.hash(userobject.password_hash, salt, function(err, hash) { // hash pw 
        if(err !== null) { 
         reject(err);    // *** 
        else { 
         userobject.password_hash = hash; // store hash in user obj 
         var user = new User(userobject); 
         resolve(user.save());  // *** save user in mongoDB 
        } 
       }); 
      } 
     }); 
    }); 
}; 

はまた、私ドンことに注意してくださいaddUserはちょうど嚥下エラーがありません。代わりに、それらは発信者に伝播します。呼び出し側はそれらを処理する必要があります( "handling"が単にロギングであっても)。

1

this.addUserというPromiseフォームを返さない場合は、bcryptに基づいてコールバックをPromisesに変換する必要があります。 bcrypt API全体を変換して、プロミスベースの関数をサポートすることができます。ブルーバードライブラリのpromisifyAll、またはそれは、手動でこの方法のようにnew Promiseを使用してください:

this.addUser = function(userobject) { 
    return new Promise((resolve, reject) => { 
     bcrypt.genSalt(10, (err, salt) => { 
     if (err) { 
      reject(err); 
     } else { 
      bcrypt.hash(userobject.password_hash, salt, function(err, hash) { 
      if (err) { 
       reject(err) 
      } else { 
       resolve(hash) 
      } 
      }) 
     } 
     }); 
    }) 
    .then(hash => { 
     userobject.password_hash = hash; // store hash in user obj 
     var user = new User(userobject); 
     return user.save() // save user in mongoDB 
    }) 
    .catch(function(err) { 
     console.log(err); 
    }); 
} 

か、その方法:

this.addUser = function(userobject) { 
    return new Promise((resolve, reject) => { 
     bcrypt.genSalt(10, (err, salt) => { 
     if (err) { 
      reject(err); 
     } else { 
      resolve(salt); 
     } 
     }); 
    }) 
    .then(salt => { 
     return new Promise((resolve, reject) => { 
     bcrypt.hash(userobject.password_hash, salt, function(err, hash) { 
      if (err) { 
      reject(err) 
      } else { 
      resolve(hash) 
      } 
     }) 
     }) 
    }) 
    .then(hash => { 
     userobject.password_hash = hash; // store hash in user obj 
     var user = new User(userobject); 
     return user.save() // save user in mongoDB 
    }) 
    .catch(function(err) { 
     console.log(err); 
    }); 
} 
0

いくつかは、よりbcryptjsの変更ログに掘り行った後、私は彼らことが判明約束を追加しましたが、ドキュメントを更新しませんでした。コールバックが省略された場合、genSalt enハッシュメソッドは約束を返します。これは次のように解釈されます:

this.addUser = function(userobject) { 
    return bcrypt.genSalt(10).then((salt) => { 
     return bcrypt.hash(userobject.password, salt).then((hash) => { 
      userobject.password_hash = hash; 
      var user = new User(userobject); 
      return user.save(); 
     }); 
    }); 
}; 
関連する問題