How to access/return values from mongo document with mongoose query and async-await/Promise?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I have used mongoDB but I am new to Node.js and mongoose and I am trying to get a grasp on using mongoose with async-await/Promises. I am creating an React/Node with web sockets (socket.io) app where users can create an account and log in if they already have an account. I have been able to successfully create and execute a mongo/mogoose query but I am having problems with using the document once I have it. This is what my code looks like:



const profileRoute = (action, io) => {
switch (action.cmd) {
case 'LOGIN':
getProfile(action.email)
.then(profile => {
console.log('profile: ', profile) // prints the mongo document properly.
console.log('email: ', profile.email) // email: undefined
io.emit('action', {
type: PROFILE_LOGIN,
email: profile.email,
name: profile.name,
});
.catch(err => {console.log(err)});
break;
default:
break;
}
};


And this is what "getProfile()" looks like:



export const getProfile = async (email) => {
const tempPromise = collection.findOne({ email }).exec();
try {
return await tempPromise;
} catch (err) {
console.log(err);
return {};
}
};


I have also tried to symplify "getProfile()" since async-await wouldn't help much here (just wanted to try something small to get started) to this:



export const getProfile = (email) => {
return collection.findOne({ email }).exec();
};


But either way I try when I print "profile.email" it is undefined and my result from



io.emit('action', {
type: PROFILE_LOGIN,
email: profile.email,
name: profile.name,
});


is:



{
type: PROFILE_LOGIN,
}


but if I do this:



io.emit('action', {
type: PROFILE_LOGIN,
profile: profile,
});


the result is:



{
type: PROFILE_LOGIN,
profile: {correct mongo document},
}


But I only need/want a few values from the mongo document.



Also, if there is a better way to rewrite "profileRoute()" (I know this question isn't really about that) using async-await I am open to suggestions.



EDIT: There was a typo when I originally wrote this question. Changed:



{
type: PROFILE_LOGIN,
profile: [correct mongo document],
}


This more accurately reflects the return from ".findOne()":



{
type: PROFILE_LOGIN,
profile: {correct mongo document},
}









share|improve this question

























  • I think that the result you get is an array of objects matching the query. try to print profile[0].email

    – dima golovin
    Jan 3 at 13:49











  • ".findOne()" only returns a single document so it is typeof == 'object' and not an array.

    – user2655025
    Jan 3 at 14:17


















0















I have used mongoDB but I am new to Node.js and mongoose and I am trying to get a grasp on using mongoose with async-await/Promises. I am creating an React/Node with web sockets (socket.io) app where users can create an account and log in if they already have an account. I have been able to successfully create and execute a mongo/mogoose query but I am having problems with using the document once I have it. This is what my code looks like:



const profileRoute = (action, io) => {
switch (action.cmd) {
case 'LOGIN':
getProfile(action.email)
.then(profile => {
console.log('profile: ', profile) // prints the mongo document properly.
console.log('email: ', profile.email) // email: undefined
io.emit('action', {
type: PROFILE_LOGIN,
email: profile.email,
name: profile.name,
});
.catch(err => {console.log(err)});
break;
default:
break;
}
};


And this is what "getProfile()" looks like:



export const getProfile = async (email) => {
const tempPromise = collection.findOne({ email }).exec();
try {
return await tempPromise;
} catch (err) {
console.log(err);
return {};
}
};


I have also tried to symplify "getProfile()" since async-await wouldn't help much here (just wanted to try something small to get started) to this:



export const getProfile = (email) => {
return collection.findOne({ email }).exec();
};


But either way I try when I print "profile.email" it is undefined and my result from



io.emit('action', {
type: PROFILE_LOGIN,
email: profile.email,
name: profile.name,
});


is:



{
type: PROFILE_LOGIN,
}


but if I do this:



io.emit('action', {
type: PROFILE_LOGIN,
profile: profile,
});


the result is:



{
type: PROFILE_LOGIN,
profile: {correct mongo document},
}


But I only need/want a few values from the mongo document.



Also, if there is a better way to rewrite "profileRoute()" (I know this question isn't really about that) using async-await I am open to suggestions.



EDIT: There was a typo when I originally wrote this question. Changed:



{
type: PROFILE_LOGIN,
profile: [correct mongo document],
}


This more accurately reflects the return from ".findOne()":



{
type: PROFILE_LOGIN,
profile: {correct mongo document},
}









share|improve this question

























  • I think that the result you get is an array of objects matching the query. try to print profile[0].email

    – dima golovin
    Jan 3 at 13:49











  • ".findOne()" only returns a single document so it is typeof == 'object' and not an array.

    – user2655025
    Jan 3 at 14:17














0












0








0








I have used mongoDB but I am new to Node.js and mongoose and I am trying to get a grasp on using mongoose with async-await/Promises. I am creating an React/Node with web sockets (socket.io) app where users can create an account and log in if they already have an account. I have been able to successfully create and execute a mongo/mogoose query but I am having problems with using the document once I have it. This is what my code looks like:



const profileRoute = (action, io) => {
switch (action.cmd) {
case 'LOGIN':
getProfile(action.email)
.then(profile => {
console.log('profile: ', profile) // prints the mongo document properly.
console.log('email: ', profile.email) // email: undefined
io.emit('action', {
type: PROFILE_LOGIN,
email: profile.email,
name: profile.name,
});
.catch(err => {console.log(err)});
break;
default:
break;
}
};


And this is what "getProfile()" looks like:



export const getProfile = async (email) => {
const tempPromise = collection.findOne({ email }).exec();
try {
return await tempPromise;
} catch (err) {
console.log(err);
return {};
}
};


I have also tried to symplify "getProfile()" since async-await wouldn't help much here (just wanted to try something small to get started) to this:



export const getProfile = (email) => {
return collection.findOne({ email }).exec();
};


But either way I try when I print "profile.email" it is undefined and my result from



io.emit('action', {
type: PROFILE_LOGIN,
email: profile.email,
name: profile.name,
});


is:



{
type: PROFILE_LOGIN,
}


but if I do this:



io.emit('action', {
type: PROFILE_LOGIN,
profile: profile,
});


the result is:



{
type: PROFILE_LOGIN,
profile: {correct mongo document},
}


But I only need/want a few values from the mongo document.



Also, if there is a better way to rewrite "profileRoute()" (I know this question isn't really about that) using async-await I am open to suggestions.



EDIT: There was a typo when I originally wrote this question. Changed:



{
type: PROFILE_LOGIN,
profile: [correct mongo document],
}


This more accurately reflects the return from ".findOne()":



{
type: PROFILE_LOGIN,
profile: {correct mongo document},
}









share|improve this question
















I have used mongoDB but I am new to Node.js and mongoose and I am trying to get a grasp on using mongoose with async-await/Promises. I am creating an React/Node with web sockets (socket.io) app where users can create an account and log in if they already have an account. I have been able to successfully create and execute a mongo/mogoose query but I am having problems with using the document once I have it. This is what my code looks like:



const profileRoute = (action, io) => {
switch (action.cmd) {
case 'LOGIN':
getProfile(action.email)
.then(profile => {
console.log('profile: ', profile) // prints the mongo document properly.
console.log('email: ', profile.email) // email: undefined
io.emit('action', {
type: PROFILE_LOGIN,
email: profile.email,
name: profile.name,
});
.catch(err => {console.log(err)});
break;
default:
break;
}
};


And this is what "getProfile()" looks like:



export const getProfile = async (email) => {
const tempPromise = collection.findOne({ email }).exec();
try {
return await tempPromise;
} catch (err) {
console.log(err);
return {};
}
};


I have also tried to symplify "getProfile()" since async-await wouldn't help much here (just wanted to try something small to get started) to this:



export const getProfile = (email) => {
return collection.findOne({ email }).exec();
};


But either way I try when I print "profile.email" it is undefined and my result from



io.emit('action', {
type: PROFILE_LOGIN,
email: profile.email,
name: profile.name,
});


is:



{
type: PROFILE_LOGIN,
}


but if I do this:



io.emit('action', {
type: PROFILE_LOGIN,
profile: profile,
});


the result is:



{
type: PROFILE_LOGIN,
profile: {correct mongo document},
}


But I only need/want a few values from the mongo document.



Also, if there is a better way to rewrite "profileRoute()" (I know this question isn't really about that) using async-await I am open to suggestions.



EDIT: There was a typo when I originally wrote this question. Changed:



{
type: PROFILE_LOGIN,
profile: [correct mongo document],
}


This more accurately reflects the return from ".findOne()":



{
type: PROFILE_LOGIN,
profile: {correct mongo document},
}






node.js mongodb mongoose promise async-await






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 14:12







user2655025

















asked Jan 3 at 13:21









user2655025user2655025

164




164













  • I think that the result you get is an array of objects matching the query. try to print profile[0].email

    – dima golovin
    Jan 3 at 13:49











  • ".findOne()" only returns a single document so it is typeof == 'object' and not an array.

    – user2655025
    Jan 3 at 14:17



















  • I think that the result you get is an array of objects matching the query. try to print profile[0].email

    – dima golovin
    Jan 3 at 13:49











  • ".findOne()" only returns a single document so it is typeof == 'object' and not an array.

    – user2655025
    Jan 3 at 14:17

















I think that the result you get is an array of objects matching the query. try to print profile[0].email

– dima golovin
Jan 3 at 13:49





I think that the result you get is an array of objects matching the query. try to print profile[0].email

– dima golovin
Jan 3 at 13:49













".findOne()" only returns a single document so it is typeof == 'object' and not an array.

– user2655025
Jan 3 at 14:17





".findOne()" only returns a single document so it is typeof == 'object' and not an array.

– user2655025
Jan 3 at 14:17












2 Answers
2






active

oldest

votes


















1














const profileRoute = async (action, io) => {
switch (action.cmd) {
case 'LOGIN':
try {
const profile = await getProfile(action.email);
if (!profile) {
throw new Error(`Profile with email ${action.email} not found`);
}
io.emit('action', {
type: PROFILE_LOGIN,
email: profile.email,
name: profile.name
});
} catch (e) {
console.log(e);
}
break;
default:
break;
}
};


And your getProfile() code would simply be:



export const getProfile = email => {
return collection.findOne({ email }).exec();
};





share|improve this answer































    -1














    export const getProfile = async (email) => {
    const tempPromise = collection.findOne({ email }).exec();
    try {
    return await tempPromise;
    } catch (err) {
    console.log(err);
    return {};
    } };


    You should add await in front of collection.findOne
    And if you wanna only get json object, you can add lean() in the end of mongoose query like this.



    export const getProfile = async (email) => {
    const tempPromise = await collection.findOne({ email }).lean().exec();
    try {
    return await tempPromise;
    } catch (err) {
    console.log(err);
    return {};
    }
    };





    share|improve this answer
























    • This worked! With how this is setup is the await necessary in front of collection.findOne()? I tried it both ways (with adding .lean() both times) and it seems to be working both ways.

      – user2655025
      Jan 3 at 14:42











    • This makes no sense. An awaited expression never resolves to a tempPromise that could subsequently be awaited again.

      – Bergi
      Jan 3 at 19:53











    • In the second example tempPromise is not a promise, it is a JSON object, so it can't be awaited again.

      – Will Garcia
      Jan 3 at 21:38











    • tempPromise is not Promise but collection exec() has promise function so it just return promise return value and lean() is supporting json object to reduce the mongoose query size.

      – superdev810
      Jan 4 at 5:05












    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54023140%2fhow-to-access-return-values-from-mongo-document-with-mongoose-query-and-async-aw%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    const profileRoute = async (action, io) => {
    switch (action.cmd) {
    case 'LOGIN':
    try {
    const profile = await getProfile(action.email);
    if (!profile) {
    throw new Error(`Profile with email ${action.email} not found`);
    }
    io.emit('action', {
    type: PROFILE_LOGIN,
    email: profile.email,
    name: profile.name
    });
    } catch (e) {
    console.log(e);
    }
    break;
    default:
    break;
    }
    };


    And your getProfile() code would simply be:



    export const getProfile = email => {
    return collection.findOne({ email }).exec();
    };





    share|improve this answer




























      1














      const profileRoute = async (action, io) => {
      switch (action.cmd) {
      case 'LOGIN':
      try {
      const profile = await getProfile(action.email);
      if (!profile) {
      throw new Error(`Profile with email ${action.email} not found`);
      }
      io.emit('action', {
      type: PROFILE_LOGIN,
      email: profile.email,
      name: profile.name
      });
      } catch (e) {
      console.log(e);
      }
      break;
      default:
      break;
      }
      };


      And your getProfile() code would simply be:



      export const getProfile = email => {
      return collection.findOne({ email }).exec();
      };





      share|improve this answer


























        1












        1








        1







        const profileRoute = async (action, io) => {
        switch (action.cmd) {
        case 'LOGIN':
        try {
        const profile = await getProfile(action.email);
        if (!profile) {
        throw new Error(`Profile with email ${action.email} not found`);
        }
        io.emit('action', {
        type: PROFILE_LOGIN,
        email: profile.email,
        name: profile.name
        });
        } catch (e) {
        console.log(e);
        }
        break;
        default:
        break;
        }
        };


        And your getProfile() code would simply be:



        export const getProfile = email => {
        return collection.findOne({ email }).exec();
        };





        share|improve this answer













        const profileRoute = async (action, io) => {
        switch (action.cmd) {
        case 'LOGIN':
        try {
        const profile = await getProfile(action.email);
        if (!profile) {
        throw new Error(`Profile with email ${action.email} not found`);
        }
        io.emit('action', {
        type: PROFILE_LOGIN,
        email: profile.email,
        name: profile.name
        });
        } catch (e) {
        console.log(e);
        }
        break;
        default:
        break;
        }
        };


        And your getProfile() code would simply be:



        export const getProfile = email => {
        return collection.findOne({ email }).exec();
        };






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 3 at 21:35









        Will GarciaWill Garcia

        11816




        11816

























            -1














            export const getProfile = async (email) => {
            const tempPromise = collection.findOne({ email }).exec();
            try {
            return await tempPromise;
            } catch (err) {
            console.log(err);
            return {};
            } };


            You should add await in front of collection.findOne
            And if you wanna only get json object, you can add lean() in the end of mongoose query like this.



            export const getProfile = async (email) => {
            const tempPromise = await collection.findOne({ email }).lean().exec();
            try {
            return await tempPromise;
            } catch (err) {
            console.log(err);
            return {};
            }
            };





            share|improve this answer
























            • This worked! With how this is setup is the await necessary in front of collection.findOne()? I tried it both ways (with adding .lean() both times) and it seems to be working both ways.

              – user2655025
              Jan 3 at 14:42











            • This makes no sense. An awaited expression never resolves to a tempPromise that could subsequently be awaited again.

              – Bergi
              Jan 3 at 19:53











            • In the second example tempPromise is not a promise, it is a JSON object, so it can't be awaited again.

              – Will Garcia
              Jan 3 at 21:38











            • tempPromise is not Promise but collection exec() has promise function so it just return promise return value and lean() is supporting json object to reduce the mongoose query size.

              – superdev810
              Jan 4 at 5:05
















            -1














            export const getProfile = async (email) => {
            const tempPromise = collection.findOne({ email }).exec();
            try {
            return await tempPromise;
            } catch (err) {
            console.log(err);
            return {};
            } };


            You should add await in front of collection.findOne
            And if you wanna only get json object, you can add lean() in the end of mongoose query like this.



            export const getProfile = async (email) => {
            const tempPromise = await collection.findOne({ email }).lean().exec();
            try {
            return await tempPromise;
            } catch (err) {
            console.log(err);
            return {};
            }
            };





            share|improve this answer
























            • This worked! With how this is setup is the await necessary in front of collection.findOne()? I tried it both ways (with adding .lean() both times) and it seems to be working both ways.

              – user2655025
              Jan 3 at 14:42











            • This makes no sense. An awaited expression never resolves to a tempPromise that could subsequently be awaited again.

              – Bergi
              Jan 3 at 19:53











            • In the second example tempPromise is not a promise, it is a JSON object, so it can't be awaited again.

              – Will Garcia
              Jan 3 at 21:38











            • tempPromise is not Promise but collection exec() has promise function so it just return promise return value and lean() is supporting json object to reduce the mongoose query size.

              – superdev810
              Jan 4 at 5:05














            -1












            -1








            -1







            export const getProfile = async (email) => {
            const tempPromise = collection.findOne({ email }).exec();
            try {
            return await tempPromise;
            } catch (err) {
            console.log(err);
            return {};
            } };


            You should add await in front of collection.findOne
            And if you wanna only get json object, you can add lean() in the end of mongoose query like this.



            export const getProfile = async (email) => {
            const tempPromise = await collection.findOne({ email }).lean().exec();
            try {
            return await tempPromise;
            } catch (err) {
            console.log(err);
            return {};
            }
            };





            share|improve this answer













            export const getProfile = async (email) => {
            const tempPromise = collection.findOne({ email }).exec();
            try {
            return await tempPromise;
            } catch (err) {
            console.log(err);
            return {};
            } };


            You should add await in front of collection.findOne
            And if you wanna only get json object, you can add lean() in the end of mongoose query like this.



            export const getProfile = async (email) => {
            const tempPromise = await collection.findOne({ email }).lean().exec();
            try {
            return await tempPromise;
            } catch (err) {
            console.log(err);
            return {};
            }
            };






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 3 at 14:18









            superdev810superdev810

            344




            344













            • This worked! With how this is setup is the await necessary in front of collection.findOne()? I tried it both ways (with adding .lean() both times) and it seems to be working both ways.

              – user2655025
              Jan 3 at 14:42











            • This makes no sense. An awaited expression never resolves to a tempPromise that could subsequently be awaited again.

              – Bergi
              Jan 3 at 19:53











            • In the second example tempPromise is not a promise, it is a JSON object, so it can't be awaited again.

              – Will Garcia
              Jan 3 at 21:38











            • tempPromise is not Promise but collection exec() has promise function so it just return promise return value and lean() is supporting json object to reduce the mongoose query size.

              – superdev810
              Jan 4 at 5:05



















            • This worked! With how this is setup is the await necessary in front of collection.findOne()? I tried it both ways (with adding .lean() both times) and it seems to be working both ways.

              – user2655025
              Jan 3 at 14:42











            • This makes no sense. An awaited expression never resolves to a tempPromise that could subsequently be awaited again.

              – Bergi
              Jan 3 at 19:53











            • In the second example tempPromise is not a promise, it is a JSON object, so it can't be awaited again.

              – Will Garcia
              Jan 3 at 21:38











            • tempPromise is not Promise but collection exec() has promise function so it just return promise return value and lean() is supporting json object to reduce the mongoose query size.

              – superdev810
              Jan 4 at 5:05

















            This worked! With how this is setup is the await necessary in front of collection.findOne()? I tried it both ways (with adding .lean() both times) and it seems to be working both ways.

            – user2655025
            Jan 3 at 14:42





            This worked! With how this is setup is the await necessary in front of collection.findOne()? I tried it both ways (with adding .lean() both times) and it seems to be working both ways.

            – user2655025
            Jan 3 at 14:42













            This makes no sense. An awaited expression never resolves to a tempPromise that could subsequently be awaited again.

            – Bergi
            Jan 3 at 19:53





            This makes no sense. An awaited expression never resolves to a tempPromise that could subsequently be awaited again.

            – Bergi
            Jan 3 at 19:53













            In the second example tempPromise is not a promise, it is a JSON object, so it can't be awaited again.

            – Will Garcia
            Jan 3 at 21:38





            In the second example tempPromise is not a promise, it is a JSON object, so it can't be awaited again.

            – Will Garcia
            Jan 3 at 21:38













            tempPromise is not Promise but collection exec() has promise function so it just return promise return value and lean() is supporting json object to reduce the mongoose query size.

            – superdev810
            Jan 4 at 5:05





            tempPromise is not Promise but collection exec() has promise function so it just return promise return value and lean() is supporting json object to reduce the mongoose query size.

            – superdev810
            Jan 4 at 5:05


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54023140%2fhow-to-access-return-values-from-mongo-document-with-mongoose-query-and-async-aw%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            Npm cannot find a required file even through it is in the searched directory