1

I can't seem to make this work but I want to return true every-time the function executes successfully, which in this case is "Changing the password".

async function ChangePassword(data) { const auth = getAuth(); let res = false; const credential = EmailAuthProvider.credential( auth.currentUser.email, data.oldPassword ); reauthenticateWithCredential(auth.currentUser, credential) .then(() => { updatePassword(auth.currentUser, data.password) .then(() => { toast.success("Password changed successfully"); res = true; console.log("res ",res); }) .catch((error) => { toast.error(error.message); }); }) .catch((error) => { toast.error(error.message); }); return res; } 

The res variable when called by other functions always results in false even though I see the toast message "Password changed successfully".

async function changePassword() { if (password === "" || confirmPassword === "" || oldPassword === "") { toast.error("Please fill all the fields"); } else if (password !== confirmPassword) { toast.error("Passwords do not match"); } else { let data = { oldPassword, password }; await ChangePassword(data).then((res) => { if (res === true) { setChangePasswordModal(false); setOpen(false); } }); } } 

The if condition in above code never executes because res is always false. I know it has something to do with async await but can't figure out how to make it work

2
  • 1
    Oh god. Mixing Promise with synchronous code + async is going to setup you up for a bad time. Commented Nov 29, 2022 at 17:15
  • 2
    Either use Promise.then and alike, or async but please NOT both. Commented Nov 29, 2022 at 17:15

1 Answer 1

1
async function ChangePassword(data) { const auth = getAuth(); let res = false; const credential = EmailAuthProvider.credential( auth.currentUser.email, data.oldPassword ); reauthenticateWithCredential(auth.currentUser, credential) .then(() => { updatePassword(auth.currentUser, data.password) .then(() => { toast.success("Password changed successfully"); res = true; console.log("res ",res); }) .catch((error) => { toast.error(error.message); }); }) .catch((error) => { toast.error(error.message); }); return res; } 

Has many logical errors in it.

First you should decide whether you're going to use async and its feature await or classical Promise .thenable -style. Please do not use both, it will only confuse you and the reader.

Let's ditch the async (since you don't even use await), and Promises are chainable, you do not (and MUST not) nest .then blocks, use this instead:

function ChangePassword(data) { const auth = getAuth(); const credential = EmailAuthProvider.credential(auth.currentUser.email, data.oldPassword); return reauthenticateWithCredential(auth.currentUser, credential) .then(() => { return updatePassword(auth.currentUser, data.password) }) .then(() => { toast.success("Password changed successfully"); return true; }) .catch((error) => { toast.error(error.message); return false; }) } 

The key here is that ChangePassword itself returns a Promise.*

The caller is then responsible to call it with .then or use async in combination with await:

ChangePassword({/* data */}).then((result) => { console.log("ChangePassword done", result) }) 

The same code looks a lot cleaner if you use async:

async function ChangePassword(data) { const auth = getAuth(); const credential = EmailAuthProvider.credential(auth.currentUser.email, data.oldPassword); try { await reauthenticateWithCredential(auth.currentUser, credential); await updatePassword(auth.currentUser, data.password); toast.success("Password changed successfully"); return true; } catch (error) { toast.error(error.message); return false; } } 

(If you were wondering how that would look like).

*a function tagged as async ALWAYS returns a promise, by the way.

Sign up to request clarification or add additional context in comments.

2 Comments

This makes it easier to understand. Thank you!
@SahilN You're welcome. I know, Promises can be confusing at first. Please remember to not mix async with .then and friends. The key (of understanding Promises) is that you chain them together with .then blocks because you're relying on a value that is not (yet) available. It's like this: each part of the "chain" is executed as soon as the value is known. When that is, is not known until runtime (you run the code). You can return another Promise from a .then() block, so you don't have to nest .then() blocks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.