1

I am trying to get a shared key based on whether it already exists in the db or not. I am using Firebase store database.
The problem is that even though i assign passkey some value inside the sub-function, when I do console.log outside the function, it just prints the original passkey which was set at declaration.
I have tried using window.passkey and window.global.passkey by declaring passkey as global variable, outside all functions, but it didn't work.
I am working with a node.js project. My code is as follows:

// var passkey = {"shared_key":""} // Declaring passkey as global variable but didn't work.
const onSubmit = (formData) => {
        const email_id = getUserDetails().email;
        const from_db = db.collection(email_id); 
        const to_db = db.collection(formData.to);
        var passkey = {"shared_key": ""};

        // Check if there exists a shared key between `from` and `to`
        // Checking for shared key in either of the db is enough.
        to_db.doc(email_id).get().then((res) => {
            // assume that res.exists is true.
            if (res.exists) {
                passkey.shared_key = res.data().shared_key; // passkey is set here
            } else {
                // Generate and use a shared key
                ...some code to generate a shared key ...
                passkey.shared_key = generated_key;
            }
        });
        console.log(passkey); 
// above prints {"shared_key": ""} instead of printing the value of shared key taken from the database.
// or the one that is generated!
};

I know it is related to variable hoisting in javascript but I think there has to be some workaround. Any help/comment is appreciated. Thanks in advance.

Joe
  • 41,484
  • 20
  • 104
  • 125
  • 4
    This has nothing to do with hoisting, it's all about [the scope of the variables](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) and [asynchronous coding](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron). – Teemu Mar 20 '21 at 12:29

1 Answers1

2

When you code with this pattern

function doIt () {
  var something = ''
  invokeFunction()
  .then (function handleResult (result) {
     console.log('2', something)
     something = result
  } )
  console.log('1', something)
}

your console.log('1', something) runs before the inner function (I named it handleResult for clarity) is ever called. That's because invokeFunction() is asynchronous; it returns a Promise object.

You could rewrite this as follows:

async function doIt () {
  var something = await invokeFunction()
  console.log('1', something)
}

to get the kind of result you want.

With respect, you will have a very hard time coding Javascript unless you take the time to learn about async / await and Promises. In that respect the Javascript language is very different from other languages. Drop everything and learn that stuff now. Seriously.

O. Jones
  • 103,626
  • 17
  • 118
  • 172