0

So I'm new to Javascript (mostly a Python person) and I'm having trouble understanding some really strange behaviors.

Long story short - I have an object in the databse (firebase firestore) that I'm trying to return. Right after I fetch it, I do a console.log and see the object in the console, and it's there! However when I return the same object...it shows as "noname" :(

Here is the code

function load_name() {
    var db = firebase.firestore();
    var name = "noname";
    var docRef = db.collection("cities").doc("SF");
    docRef.get().then(function (doc) {
            if (doc.exists) {
                name = doc.data().name;
                //following shows as 'San Francisco' in console
                console.log(name); 
                return name; //Added this line later to see if issue is fixed, but it didn't fix it.
            } else {
                // doc.data() will be undefined in this case
                console.log("No such document!");
            }
        }
    ).catch(function (error) {
        console.log("Error getting document:", error);
    });
    return name;
}
myname = load_name();
//^prints 'San Francisco' on console, but returns as undefined. 

I've spent about 5 hours on this. Any help would be appreciated!

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • FYI if you want to format some code, don't just intend the first and last lines. You can format the entire thing by using the {} button in the editor. – Doug Stevenson Jan 15 '19 at 22:32

1 Answers1

1

Unlike python, JavaScript APIs are all asynchronous. When you call get(), it returns immediately with a promise that resolves when the work is complete. then() also returns a promise, and so does catch(). You are returning name before it ever receives a value from the callback, which happens some time later.

If you want to write a function that lets the caller receive the results of some async work, you should return a promise that resolves with the results of the work, then the caller can use then() on that promise to listen for the results.

Basically, you are going to have to become more familiar with the conventions JavaScript uses for dealing with async work and promises.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Thanks man! This helped a lot. Finally learned about callback hell - I think i'll stick to python ;) – Shafiq Mohammed Jan 16 '19 at 17:09
  • Node is actually a superior runtime, and the syntax gets cleaner with async/await. (you're using old style then callbacks). But of course you should do what's effective for you. – Doug Stevenson Jan 16 '19 at 17:20
  • so do you recommend implementing a node backend? – Shafiq Mohammed Jan 18 '19 at 18:06
  • The python runtime for Cloud Functions is currently in beta, while nodejs is fully productionized. It also makes it easier for you to write more efficient code. It's my preference. – Doug Stevenson Jan 18 '19 at 18:31