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
Advertisement
Answer
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 .then
able -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 Promise
s 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.