0

I am trying to save the result of findOne(), however, I do not have any idea how to save this result in a variable.

function createSubscription (req, res, next) {
  let product_id = "P-5JM98005MT260873LLT44E2Y" ;
  let doc = null;
  product.findOne({"plans.id": product_id}, { "plans.$": 1 
  }).sort({create_time: -1}).exec(function(err, docs) {  
    if(err) {
    } else {
      if(docs != null) {
        this.doc = docs;
      } 
    }
  });
  console.log(doc);
  let result = null;
  if (doc.create != null) {
    result = processDoc(doc);
  }
}

function processDoc(doc) {
   //do something 
  return resul;
}

function processResult(result) {
  //do something
}


Below, I copy the product schema

const mongoose = require('mongoose');

const Schema = mongoose.Schema;
const ProductSchema = new Schema({
    id: {
        type: String,
        trim: true,
        required: true,
    },
    name: {
        type: String,
        required: true,
    },
    description: {
        type: String,
        required: true,
    },
    create_time: {
        type: Date,
        required: true,
    }
});
module.exports = mongoose.model('Product', ProductSchema);

The doc is always null and does not receive the value.

In general terms, I would like to get the response product.findOne to use another function, calling by createSubscription()

nilsonjr
  • 66
  • 1
  • 8
  • Hi nilsonjr, more context is needed in order to assist. Can you provide all relevant contents. It would be helpful to see where `product` is coming from and what the `product` schema looks like. – dillon Jun 13 '19 at 02:52
  • I've updated the code – nilsonjr Jun 13 '19 at 03:35
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – zero298 Jun 13 '19 at 04:29

3 Answers3

2

To save the result of findOne() is as easy as this:

var doc = product.findOne();

The problem you're having is that you are calling processDoc() before findOne() is finished. Look into asynchronous javascript. You can fix this by using async/await like this:

async function createSubscription (req, res, next) {
    var doc = await product.findOne();
    processDoc(doc);
}
RyanSurv
  • 46
  • 4
0

The reason is you are calling a callback function, which means function is asynchronous. So there is no guarantee that your query will execute and the values will be set before it reaches to,

  if (doc.create != null) {
    result = processDoc(doc);
  }

To resolve this you may use the Async/Await Syntax:

const createSubscription = async function (params) { 
    try {  return await User.findOne(params)
    } catch(err) { console.log(err) }
}

const doc = createSubscription({"plans.id": product_id})
Anjana
  • 903
  • 1
  • 5
  • 13
0

Since you want to query something in database, that means you already created one and saved some data in it.

However before saving data in the database you should be creating your model which should be created under models folder in Product.js(model names should start capital letter in convention) . Then you have to IMPORT it in your above page to access it. You want to query by product.id but which product's id?

Since you have req in your function, that means you are posting something. If you set up the proper settings in app.js you should be able to access to req.body which is the information that being posted by the client side.

app.js //setting for parsing(reading or accessing) req.body

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

Now we can reach req.body.id

this should be your code:

function createSubscription (req, res, next) {
const product=Product.findOne({plan.id:req.body.id})
.
.
}

If you noticed I did not put this plan.id in quotes.Because findOne() method belongs the Product model and that model belongs to the package that you are using. (In mongoose you query without quotes, in mongodb client you query in quotes)

findOne() is an asynchronous operation means result will not come to you immediately. So you should always keep it in try/catch block.

function createSubscription (req, res, next) {
try{
const product=Product.findOne({plan.id:req.body.id})
}
catch(error){console.log(error.message)} //every error object has message property
.
.
}

Lastly since you are querying only one object you do not need to sort it.

Yilmaz
  • 35,338
  • 10
  • 157
  • 202