0

Here I'm creating an array that have property 1, then I'm trying to filter the results with only the highest number and then output it when calling the function, but it returns undefined. I'm trying to find to figure out what I'm doing wrong here. Thanks

function calcDifference() {
  table.find({
      "entries": 1
    }) // select entries with "entries":1
    .toArray(function(err, res_spr) { // create an array of found elements 
      let pop = res_spr.pop(); // delete last element of the array
      let storeArraySpr = []; // new array to store property "number"
      for (let i = 0; i < res_spr.length; i++) {
        storeArraySpr.push(res_spr[i].number);
      }

      var resultSpr = Math.max(...storeArraySpr); // select highest entry
      return resultSpr.toFixed(8); // meant to output the result when calling the function
    });
}

console.log(calcDifference()); // returns undefined
7
  • 2
    Change table.find to return table.find Commented May 12, 2022 at 16:54
  • @Barmar still returns undefined Commented May 12, 2022 at 17:03
  • What is table? Commented May 12, 2022 at 17:08
  • 2
    toArray() is an asynchronous function. You need to use await. Commented May 12, 2022 at 17:13
  • 2
    When toArray() is called with a callback function, it doesn't return anything. See mongodb.github.io/node-mongodb-native/4.5/classes/… Commented May 12, 2022 at 17:16

2 Answers 2

1

You haven't returned anything from that function.

You should add return before table.find

function calcDifference(){

      return table.find({"entries":1}) // select entries with "entries":1

        .toArray(function(err, res_spr) { // create an array of found elements 
 
              let pop = res_spr.pop(); // delete last element of the array

              let storeArraySpr = []; // new array to store property "number"

              for (let i = 0; i < res_spr.length; i++) { 

                storeArraySpr.push(res_spr[i].number); 

              }

              var resultSpr = Math.max(...storeArraySpr); // select highest entry

              return resultSpr.toFixed(8); // meant to output the result when calling the function
        });
    } 

    console.log(calcDifference()); 

If toArray does not return values in that callback function. You can assign a value and return it.

Note that this approach will work if toArray and find do not return promises

function calcDifference(){
      let result;
      table.find({"entries":1}) // select entries with "entries":1

        .toArray(function(err, res_spr) { // create an array of found elements 
 
              let pop = res_spr.pop(); // delete last element of the array

              let storeArraySpr = []; // new array to store property "number"

              for (let i = 0; i < res_spr.length; i++) { 

                storeArraySpr.push(res_spr[i].number); 

              }

              var resultSpr = Math.max(...storeArraySpr); // select highest entry

              result = resultSpr.toFixed(8); // meant to output the result when calling the function
        });

     return result; //return the final result from the callback function
    } 

    console.log(calcDifference()); 

The 3rd approach, if find and toArray are actually promises

async function calcDifference(){
      return await table.find({"entries":1}) // select entries with "entries":1

        .toArray(function(err, res_spr) { // create an array of found elements 
 
              let pop = res_spr.pop(); // delete last element of the array

              let storeArraySpr = []; // new array to store property "number"

              for (let i = 0; i < res_spr.length; i++) { 

                storeArraySpr.push(res_spr[i].number); 

              }

              var resultSpr = Math.max(...storeArraySpr); // select highest entry

              return resultSpr
        });
    } 

    console.log(await calcDifference()); 

If toArray does not return results, you can assign variable again, but the difference is now we have async/await

async function calcDifference(){
         let result;
         await table.find({"entries":1}) // select entries with "entries":1

        .toArray(function(err, res_spr) { // create an array of found elements 
 
              let pop = res_spr.pop(); // delete last element of the array

              let storeArraySpr = []; // new array to store property "number"

              for (let i = 0; i < res_spr.length; i++) { 

                storeArraySpr.push(res_spr[i].number); 

              }

              var resultSpr = Math.max(...storeArraySpr); // select highest entry

              result = resultSpr
        });
        return result
    } 

    console.log(await calcDifference()); 
Sign up to request clarification or add additional context in comments.

12 Comments

still returns undefined.
what data resultSpr do you get? I'm suspecting that resultSpr has no data @D.M.
if gets highest value out of an array of elements with Double type.
could I know which library toArray is from? @D.M.
I use mongoose and express
|
1

Your main issue is that calcDifference() doesn't have a return value. To solve this you first need to change the way you call toArray(). Like Barman pointed out in the comments:

When toArray() is called with a callback function, it doesn't return anything. See mongodb.github.io/node-mongodb-native/4.5/classes/…Barmar

When you look at the documentation you'll find that it does return a promise if you do not pass a callback function. Firstly we change calcDifference to an async function. Then we await table.find({ "entries": 1 }).toArray() instead of passing a callback. After that you can do your other stuff.

Do note that an async function always returns a promise, so to use the return value you either have to await the value, or use a then() construct if you are not in async context.

async function calcDifference() {
  const res_spr = await table.find({ "entries": 1 }).toArray(); // select entries with "entries":1
  
  let pop = res_spr.pop(); // delete last element of the array
  let storeArraySpr = []; // new array to store property "number"
  for (let i = 0; i < res_spr.length; i++) {
    storeArraySpr.push(res_spr[i].number);
  }

  var resultSpr = Math.max(...storeArraySpr); // select highest entry
  return resultSpr.toFixed(8); // meant to output the result when calling the function
}

// when in async context
console.log(await calcDifference());

// when not in async context
calcDifference().then(console.log);

// or if you need to execute multiple statements
calcDifference().then((result) => {
  console.log(result);
  // other stuff
});

3 Comments

Note that storeArraySpr can be simplified to res_spr.slice(0, -1).map(item => item.number). This allows you to remove the pop() call and the for-loop.
console.log(await calcDifference()); error on this line SyntaxError: missing ) after argument list
@D.M. Do you have console.log(await calcDifference()) placed in an async function? If not, make sure that the function wrapping the statement is converted to an async function. If it already placed inside an async function, try splitting the statement in 2. const result = await calcDifference() and console.log(result)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.