2017-09-26 4 views
1

Ich habe eine Node.js API mit einem MongoDB. Es gibt eine Route, die einen Benutzer erstellt und das Passwort hashen muss, dafür benutze ich das bcryptjs-Paket.Node.js Mungo-Versprechen gehen verloren

die Route sieht wie folgt aus:

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

und 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); 
        }); 
       } 
      }); 
     } 
    }); 
}; 

ich einen Fehler zu sagen: "nicht Eigentum lesen kann 'dann' undefinierter", die mir sagt, dass Ich bekomme kein Versprechen von addUser. Ich schaute und bcryptjs verwendet leider keine Versprechen, aber Mungo tut. (Hinzufügen dieses:

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

hat nicht geholfen)

Ich habe versucht, in ein Versprechen die Funktion Umwickeln mit verwerfen und beheben, aber das gibt diesen Fehler: „Typeerror: Versprechen Resolver undefiniert ist keine Funktion ".

Wie bekomme ich das Versprechen, dass die Funktion save() von Mungo wieder auf die .then() in der Post-Route zurückkehrt? Ich versuchte, Rückkehr vor den zwei bcrypt Funktion hinzuzufügen, aber das funktionierte auch nicht.

Irgendwelche Vorschläge sind willkommen!

+0

Sie geben kein Versprechen aus Ihrem 'this.addUser' zurück. –

+1

um klar zu sein, Sie nicht ** alles ** von 'this.addUser' zurückgeben –

+0

@Jaromanda X ja ich sehe das jetzt, ich bin neu zu versprechen und ich denke, ich verlor durch die API, die Versprechen nicht unterstützt .. –

Antwort

1

Ihre addUser Funktion nevers gibt das Versprechen an seinen Anrufer zurück. Sie tun eine return von der Callback-Funktion bcrypt.hash, aber das hat nichts mit addUser 's Rückgabewert zu tun.

Es sieht aus wie addUser hat einige nicht-Promise-fähige APIs zu verwenden, so dass Sie mit dem Tun new Promise stecken, so etwas wie dies (siehe *** Kommentare):

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 
        } 
       }); 
      } 
     }); 
    }); 
}; 

Beachten Sie auch, dass ich don 't haben addUser nur Schluckfehler; stattdessen werden sie an den Aufrufer weitergegeben. Der Aufrufer sollte sie behandeln (auch wenn "Handhabung" nur Protokollierung ist).

1

Sie geben kein Versprechen von Ihrem this.addUser zurück, Sie müssen Ihren Rückruf basierend auf bcrypt in Promises konvertieren. Sie können die gesamte API bcrypt konvertieren, um Promise-basierte Funktionen zu unterstützen, die z. promisifyAll der drossel-Bibliothek oder manuell tun new Promise wie auf diese Weise mit ihm:

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); 
    }); 
} 

Oder diese Weise:

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

ich, dass sie herausfanden, einige mehr zu graben in den Änderungsprotokolle von bcryptjs Nachdem ich hinzugefügt Versprechen, aber nicht aktualisiert die Dokumentation .. Die genSalt en-Hash-Methoden geben eine Zusage zurück, wenn die Rückrufe entfallen. Dies würde bedeuten:

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(); 
     }); 
    }); 
}; 
Verwandte Themen