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

  1. #1
    Nouveau membre du Club
    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
    Nouveau membre du Club
    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.