0

In this simplified example, associative array A cannot be populated in a Node.js Firestore query---it's as if there is a scoping issue:

var A = {};

A["name"] = "nissa";

firestore.collection("magic: the gathering")
  .get()
  .then(function(query) {
    query.forEach(function(document) {
        A[document.id] = document.id;
        console.log(A);
    });
  })
  .catch(function(error) {
});

console.log(A);

Console output:

{ name: 'nissa' } < last console.log()
{ name: 'nissa', formats: 'formats' } < first console.log() (in forEach loop)
{ name: 'nissa', formats: 'formats', releases: 'releases' } < second console.log() (in forEach loop)

Grateful for any assistance, please request for further detail if needed.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

1 Answers1

0

Data is loaded from Firestore asynchronously, and while that is happening, your main code continues to run.

It's easiest to see what that means by placing a few logging statements:

console.log("Starting to load data");
firestore.collection("magic: the gathering")
  .get()
  .then(function(query) {
    console.log("Got data");
  });
console.log("After starting to load data");

When you run this code, it prints:

Starting to load data

After starting to load data

Got data

This is probably not the order that you expected the logging to be in. But it is actually working as intended, and explains the output you see. By the time your last console.log(A); runs, the data hasn't been loaded yet, so A is empty.


The solution is simple, but typically takes some time to get used to: all code that needs the data from the database must be inside the callback, or be called from there.

So something like this:

var A = {};

A["name"] = "nissa";

firestore.collection("magic: the gathering")
  .get()
  .then(function(query) {
    query.forEach(function(document) {
        A[document.id] = document.id;
    });
    console.log(A);
  })

Also see:

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks very much Frank. Yes, it is all a bit new. How does one "return" the data to outside of the "callback, or be called from there." once the query finishes? I definitely need to change my way of thinking, but most examples I find are just simple console.log() examples of handling data post query (inside the callback). I can't conceive how to structure a program that works within callback(s) especially when that program requires more queries (thus more callbacks) from multiple collections. Thanks again. – gm20175 Apr 05 '20 at 15:27
  • The links I gave you show plenty of examples that use the data outside of the callback, although it is always used inside some callback. The only way to not need that is with `async` / `await`, for which I also included a link to an example. – Frank van Puffelen Apr 05 '20 at 15:35