IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

NodeJS Discussion :

Fonction asynchrone avec requêtes sequelize retournant undefined


Sujet :

NodeJS

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2006
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 28
    Points : 83
    Points
    83
    Par défaut Fonction asynchrone avec requêtes sequelize retournant undefined
    Bonjour,

    Je bloque depuis un moment sur une fonction déclarée comme asynchrone mais dont je n'arrive manifestement pas à attendre le résultat malgré un ".then".

    Voilà la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    async function getIdGodfather(code)
    {
        if(code.indexOf("@") !== -1)
        {
            db["User"].findOne({ attributes: ["id"], where: { email : code } })
                .then(user =>
                {
                    if(user)
                    {
                        console.log("j'ai trouvé "+user.id);
                        return user.id;
                    }
                    else
                        return null;
                });
        }
        else if (code.startsWith(config.beginCodeGodfather))
        {
            db["User"].findByPk(parseInt(code.substring(config.beginCodeGodfather.length),10), { attributes: ["id"] })
                .then((user) =>
                {
                    if(user)
                    {
                       console.log("j'ai trouvé "+user.id);
                        return user.id;
                    }
                    else
                        return null;
                });
        }
        else
            return null;
    }
    L'idée est donc ici de vérifier qu'un code de parrainage/email envoyé correspond bien à un enregistrement dans ma base de donnée et d'en retourner l'id, utile pour la suite du traitement.
    J'ai ajouté pas mal de console.log() pour chercher le bug...

    Voici comment j'appelle ensuite cette fonction dans mon routeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    getIdGodfather(req.body.codeGodfather)
                .then(id =>
                {
                     console.log("code parrain : " + id);
                });
    Lorsque je teste la route avec Postman, voici ce qui je vois dans ma console :

    code parrain : undefined
    Executing (default): SELECT `id` FROM `Users` AS `User` WHERE `User`.`email` = 'test@moi.com';
    j'ai trouvé 15
    Je constate donc que malgré le ".then", le "console.log("code parrain : " + id);" est exécuté avant que ma fonction asynchrone ne retourne quoi que ce soit, ce qui explique le "undefined".
    Mais je ne comprends pas pourquoi ?
    Surtout que la fonction est bien appelée et fait son job en trouvant bien l'enregistrement correspondant à l'email envoyé.

    Pour tester, j'ai créé un autre route qui fait à peu près la même chose que ma fonction asynchrone :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    exports.getGodfatherId = (req, res, next) =>
    {
        let code=req.params.code;
        if(code.indexOf("@") !== -1)
        {
            db["User"].findOne({ attributes: ["id"], where: { email : code } })
                .then((user) =>
                {
                    if(user)
                        res.status(200).json(user);
                    else
                        res.status(404).json(null);
                });
        }
        else if (code.startsWith(config.beginCodeGodfather))
        {
            db["User"].findByPk(parseInt(code.substring(config.beginCodeGodfather.length),10), { attributes: ["id"] })
                .then((user) =>
                {
                    if(user)
                        res.status(200).json(user);
                    else
                        res.status(404).json(null);
                });
        }
        else
            res.status(404).json(null);
    }
    Et là, tout fonctionne comme souhaité.

    Je précise que je débute avec node.js et il y a encore pas mal de trucs qui m'échappent.
    C'est peut-être aussi une erreur de syntaxe ou autre que j'ai devant le bout du nez !

    Merci pour de votre aide.

  2. #2
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2006
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 28
    Points : 83
    Points
    83
    Par défaut await m'a sauvé !?
    Je me réponds, car faute d'avoir trouvé ce qui bloquait, j'ai trouvé une solution en passant par await au lieu de .then :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    async function getIdGodfather(code)
    {
        let Godfather="";
        if(code.indexOf("@") !== -1)
        {
            Godfather=await db["User"].findOne({ attributes: ["id"], where: { email : code } });
        }
        else if (code.startsWith(config.beginCodeGodfather))
        {
            Godfather=await db["User"].findByPk(parseInt(code.substring(config.beginCodeGodfather.length),10), { attributes: ["id"] });
        }
       if(Godfather!=="")
            return Godfather;
        else
            return null;
    }
    Je peux ensuite l'appeler :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    getIdGodfather(req.body.codeGodfather)
                .then(Godfather =>
                {
                    if(Godfather)
                        req.body.GodFatherId=Godfather.id;
                    // ....
                })
                .then(() =>
                {
                    // ....
                })
                .catch(e =>
                {
                    res.status(500).json({ errors: "Erreur serveur" });
                    console.error(JSON.stringify(e, null, 4));
                });
    Et cette fois, l'objet User m'es bien retourné quand l'enregistrement est trouvé et j'arrive à intercepter les erreurs de sequelize.
    En bonus, je trouve que le code est plus lisible.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Créer une fonction générique avec requête SQL dynamique
    Par bricoreur dans le forum Langage SQL
    Réponses: 2
    Dernier message: 19/03/2019, 13h50
  2. [AJAX] Fonction success retourne “UNDEFINED” avec CFC query
    Par coeurdange dans le forum jQuery
    Réponses: 3
    Dernier message: 24/09/2015, 11h26
  3. [AC-2007] Fonction boolean avec requête
    Par Vhalar dans le forum VBA Access
    Réponses: 4
    Dernier message: 02/09/2011, 18h20
  4. this.form retourne undefined avec <a>
    Par Tchupacabra dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 11/03/2007, 09h51
  5. Réponses: 3
    Dernier message: 15/02/2007, 09h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo