0

Supposing that I have a Post schema, I want a method with this structure here:

function getPostDetails(post_id)
{
    // The function searches the db for a document with that id,
    // Finds it, and returns an object containing some of its details:
    return {
        title: post.title,
        thumbnail: post.thumbnail,
        views: post.views
        // ....
    };
 }

It must have this form, I have a lot of async, lambda, and nested functions and I don't want to make that code messier...

I did a lot of research but didn't find the way of doing it, maybe because I suck at handling promises and async code? yes!

Muhammad Nihad
  • 95
  • 2
  • 12
  • 2
    That's an object, there's no such thing as a "JSON object"; JSON is a text format. Anyway, you need to make the function `async`, `await` the DB query inside, then return the object. When calling the function, you need to also `await` the call. (once any async call enters the picture, you cannot ever go back to normal returns; you have to await everything from that point forward) –  Dec 13 '20 at 10:00
  • Thanks for your replay, Oops! my bad, I just edited that! However I think that my exact problem is how to get that data back from the query to outside the function, since that the data returned from (i.e.) the `mongoose.findById()` function exists only inside an inner function... – Muhammad Nihad Dec 13 '20 at 10:05
  • Returning the data is precisely what makes it accessible from the outside. Just do `const postData = await getPostDetails(123);` There's also this reference dupe: https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron –  Dec 13 '20 at 10:08
  • @str not exactly! – Muhammad Nihad Dec 13 '20 at 12:52
  • @ChrisG for some reason that does not work for `Post.findById(post_id)`, where Post is my mongoose model. maybe I'm just doing it wrong. Any help with a simple code sample will be very appreciated. – Muhammad Nihad Dec 13 '20 at 12:54
  • "*maybe I'm just doing it wrong*"–Please provide a [mcve] as your question is unclear. – str Dec 13 '20 at 12:58
  • @str sorry I tried so many ways so that my code became so messy, I just deleted it. but I'll try my best to explain what I need. I have a mongoose method `Post.findById(id, function(err, data) { if (err) { // return err; } else { // return data; }})` Now let's suppose that I have this line of code in a function `getPostDetails(post_id)` which should take the post id and return either `err` or `data`. but the problem here is that those 2 entities are defined only inside that anonymous function.. I don't know how to access and return them as return values for the outer function `getPostDetails` – Muhammad Nihad Dec 13 '20 at 13:08
  • I hope that's clear enough – Muhammad Nihad Dec 13 '20 at 13:09
  • 1
    Yes now it is clearer. I added a duplicate question that answers this in great detail. Alternatively, you can also use `return Post.findById(id).exec()`. Details can be found in the [documentation](https://mongoosejs.com/docs/api.html#model_Model.findById). – str Dec 13 '20 at 13:18
  • @str that lead me not only to solve my problem, but also to build a better understanding of async/await and promises in general, thanks a lot for your help, you saved me :) – Muhammad Nihad Dec 13 '20 at 15:17

1 Answers1

1

Mongoose calls are done asynchronously. They cannot be made synchronously and it is also bad idea to make DB calls synchronous.

You have 2 options, either you make function asynchronous to return promise or add a callback parameter.

Using async await.

async function getPostDetails(post_id) {
  const post = await queryDb(post_id)
  const data = map(post) // convert generic post to desire schema
  return data
}

Using promises without async / await.

function getPostDetails(post_id) {
  return queryDb(post_id).then(post => map(post))
}

Using callback.

function getPostDetails(post_id, callback) {
  queryDb(post_id).then(post => map(post)).then(post => callback(post))
}
jm18457
  • 443
  • 1
  • 7
  • 19
  • Thanks a lot for your informative answer, unfortunately I couldn't apply it to my case. The way I query the db is using `Post.findById(post_id)`, where Post is my mongoose model. any help will be appreciated! – Muhammad Nihad Dec 13 '20 at 12:51