Bonjour,
Je crée actuellement un petit blog en NodeJS pour m'entrainer au langage, cependant, je me heurte à un problème que j'essaye de résoudre depuis 2 jours :(

Ce que je fais

Pour expliquer simplement, j'ai un fichier central (server.js) et j'ai un fichier pour chacune de mes routes et enfin j'ai mes models, le problème vient des models. Dans la route de la page de l'inscription je fais appel au model User qui va notamment me permettre de faire appel à une fonction pour créer un utilisateur, voilà cependant ici arrive le problème : je veux check si il n'y a pas déjà le même email ou pseudo dans la BDD et renvoyer une erreur personalisé, du style "Ce pseudo est déjà pris". Ce que je n'arrive pas à faire c'est transmettre l'erreur depuis mon modèle jusqu'à ma route qui renverra une erreur. J'ai essayé plusieurs méthodes, notamment en suivant ce lien : http://stackoverflow.com/questions/16882938/how-to-check-if-that-data-already-exist-in-the-database-during-update-mongoose

Je ne comprend pas non plus l'utilisation des "validator" de mongoose :/

Voici mon model User :

class User {
    static create (pseudo, email, password) {
        mongoose.connect(dbUrl, (err) => {
            if (err) throw err
            bcrypt.hash(password, saltRounds, (err, hash) => {
                if (err) throw err
                let newUser = new UserModel({
                    pseudo: xss(pseudo),
                    email: xss(email),
                    password: hash
                })

                newUser.save((err) => {
                    if (err) throw err
                    mongoose.connection.close()
                })              
            })
        })
    }
}

Et ma route :

router.post('/sign-up', (req, res) => {
    if (req.body.password === req.body.repeatpassword) {
        User.create(req.body.pseudo, req.body.email, req.body.password)
        req.flash('success', "Votre compte à été créé, vous pouvez vous connecter")
        res.redirect('/login')
    } else {
        req.flash('error', "Les mots de passe ne corresponde pas")
        res.redirect('/sign-up')
    }
})

Le problème n'étant pas tellement le faite de check si un utilisateur existe déjà mais tout simplement de renvoyer l'erreur depuis le model.

Merci par avance de votre aide !

7 réponses


mxmaxime
Réponse acceptée

Salut,
Je ne peux pas t'aider sur ta question (je n'utilise pas mongodb) mais j'ai pu remarquer un problème dans ton code, qui en production pourrait vraiment te faire du tord.
Dans tes models :

if (err) throw err

Mais cette erreur n'est pas catché ?
Egalement, dans tes routes :

User.create(req.body.pseudo, req.body.email, req.body.password)
req.flash('success', "Votre compte à été créé, vous pouvez vous connecter")
res.redirect('/login')

Tu ne profites pas de l'asynchrone qu'offre JavaScript, ici ce n'est pas bien grave mais si ton application grandi ça pourrait te faire gagner beaucoup de temps.
Je te donne une piste pour améliorer :
Lorsque tu call un model, passes un callback en paramètre :

// controllers
User.create(... , ... , (err, data) => {
    if (err) res.status(500).json({error: true})
    req.flash('success', "Votre compte à été créé, vous pouvez vous connecter")
    res.redirect('/login')
})

Et dans tes models :

// models
static create (pseudo, email, password, callback) {
    // ...
    if (err) return callback(err, null)
    // ...
    return callback(null, dataFromDb)
}

Hello Neall, je n'ai malheuresement pas le temps aujourd'hui pour te donner une réponse compléte mais sache que , pour un projet perso avec nosql, j'avais besoin de validation de mes modeles mongoose et j'ai obtenu des réponses en suivant un cours de mark scott sur la plateforme pluralsight.com (introduction to Mongoose for Node.js and MongoDB). L'avant dernier chapitre est consacré à la validation des modéles. Je ne connais pas ton niveau mais il faut savoir que tu as droit un essai gratuit qui pourrais te suffire pour éclairer ta lanterne. Voici le lien : http://bit.ly/2guCkBD
[ptit disclaimer: je ne suis pas affilié].
Il est vrai que les tutos vidéos sur mongoose ne sont pas légion.
A toi de voir et bon courage.

Nealll
Auteur

Emix : Merci pour ton explication sur les callback j'ai pu résoudre mon problème et mieux organiser mon code !
Smartee : Le site que tu m'a donné est vachement bien ! Je pense que je vais regarder leurs différents cours sur Node et pas que celui sur mongoose, merci !

Merci beaucoup à vous deux !

De rien, content d'avoir pu t'aider :-)
Si tu as des questions à propos les callback n'hésite pas, si tu débutes avec js et nodejs ça peut rester flou étant donné qu'on est habitué au code synchrone.
Bonne continuation à toi ! (oublie pas de resolve le topic)

Nealll
Auteur

Bah.. Justement il y a le fameux next() dans les fonctions que je ne sais pas trop comment utiliser.
Je sais que ça permet de passer à l'instruction suivante.

Si jamais tu peux éclaircire ma lanterne, je t'en remercierai !

Salut, excuses moi pour la réponse tardive (très occupé ces temps ci)
Tu as déjà presque tout comprit sur la fonction next().
Je remets le contexte, les middlewares s'exécutent l'un après l'autre.
Exemple :

const middleware1 = (req, res, next) => {
    console.log('Hello from middleware1')
    // Do something ...
    next()
}

const middleware2 = (req, res, next) => {
    console.log('Hello from middleware2')
    // Doe something ...
    next()
}

app.get('/emix', middleware1, middleware2)

(ici je ne return pas de response, à ne jamais faire ahah) <br />
Dans la console (de mon serveur) je vais avoir le 'Hello from middleware1' puis le 'Hello from middleware2'.
Maintenant, si dans l'exécution de mon middleware1 j'ai une erreur, je veux arrêter l'exécution des autres middlewares, j'appelle la fonction next(err). <br />
De même si je fais un coup de : return res.sendStatus(200) dans middleware1 alors middleware2 ne sera pas exécuté.
J'espère avoir été claire, si tu as des questions n'hésite pas.

Nealll
Auteur

Ok ça va tout de suite mieux ! Merci