0

I am still new to Node.js and Mongoose and have no idea why this code is not returning an array. Any suggestions?

function all(array){
    array = card.cards.find({}, (err, items) => {
        array = items
        return array
    })
}

let arr = []
all(arr)
console.log(arr)

The end result is just an empty array.

Alex Yaroshevich
  • 710
  • 8
  • 19
pottonic
  • 11
  • 1
  • 1
    Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – jonrsharpe Feb 16 '20 at 22:38
  • 1
    Also reassigning the parameter name to a new array does *nothing* to the array you passed in. – jonrsharpe Feb 16 '20 at 22:39

2 Answers2

0

You don't need to pass in an array, you can return the items that are returned by the .find() method.

function getAll(){
    card.cards.find({})
         .then(items => {
             return items 
         }
         .catch(err => {
             console.log(err)
         }
}
noahdubs
  • 79
  • 1
  • 12
  • Your code won't work cuz you still not return the result. The correct answer will be `function getAll() { return card.cards.find({}); }` – Alex Yaroshevich Feb 16 '20 at 23:53
0

You have 2 problems.

1. No way to reassign variable passed as parameter inside a function:

var a = 1;
function fn(b) {
  b = 2;
}
fn(a);
a === 1; // true

Also it's a bad pattern to mutate data inside functions when it's not really needed. Better just return and assign in outer scope:

function all() {
  return card.cards.find({});
}
all(a).then(console.log); // [...]

But you can mutate an array without reassigning:

var a = [1, 2, 3];
function fn(array) {
  array.splice(0, Infinity, ...[5, 6, 7, 8]);
}
a; // [1, 2, 3]
fn(a);
a; // [5, 6, 7, 8]

2. Async calls to Mongoose and async-await/promises

Still even if you return that from function all you have to wait the result.

Calls to mongoose methods are async. It means they return Promise objects (or promises) that implements interface with methods then and catch. The function you pass to then method will be called if promise will be resolved successfully, and the function in catch will be called if the promise will be rejected.

E.g.

function p() {
  if (Math.random() > 0.5) {
    return Promise.resolve(1);
  } else {
    return Promise.reject(new Error('2'));
  }
}

p()
  .then(function (result) { /* will be called half of time for resolve branch */ })
  .catch(function (error) { /* will be called for reject branch */ })

This code is similar to but uses syntactic sugar:

async function p() {
  if (Math.random() > 0.5) return 1; // Similar to return Promise.resolve(1);
  throw new Error('2'); // Similar to return Promise.reject(new Error('2'))
}

To wait promises inside async function there is an await keyword.

async function all() {
  try {
    return await cards.find({});

  } catch(error) {
    if (false /* somehow handle mongoose errors */) {
      // check error, if db not ready just retry or do sth else
      // …
    }

    // Just rethrow if we can't do any
    throw error;
  }
}

Read more about async-await: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Alex Yaroshevich
  • 710
  • 8
  • 19