0

I have a function written to authenticate and signup a user on my react app. If successful, the function gives an alert message saying "Account Created". I have given the function a setTimeout function which should execute in 1 second and send the user to their profile. The setTimeout is simply not executing ( everything else in the function is). When I remove the setTimeout function and just send the user to their profile without any timed delay, it works properly. What is wrong with they way I'm trying to execute this?

Heres my code in my AuthContext:

import { useHistory } from 'react-router-dom'
const history = useHistory()

    function authSignup(email, password) {
    auth.createUserWithEmailAndPassword(email, password)
        .then(() => {
            setMessage("Account Created")
            setSuccess(true)
            setLoading(false)
            setTimeout(() => history.push('/'), 1000)
        })
        .catch(function (error) {

            let errorCode = error.code;
            let errorMessage = error.message;
            if (errorCode) {
                setError(errorMessage);
                setLoading(false)
            }
        })

}

And this function is being executed on a form submit:

const submitForm = async (e) => {
    e.preventDefault()
    setError('')
    setMessage('')

    if (password !== passwordConfirm) {
        return setError("Passwords do not match")
    }
    await authSignup(email, password)

    }
  • 2
    So if you replace `setTimeout(() => history.push('/'), 1000)` with `history.push('/')` everything works as expected? – codemonkey Feb 14 '21 at 22:23
  • FWIW you're `await`ing `authSignup()` which isn't returning `async` and doesn't return a promise. – root Feb 14 '21 at 22:50
  • @codemonkey yes that is correct – Brandon Austin Feb 14 '21 at 22:58
  • That's a great point @root, but the `setTimeout` should still do its job. Brandon, does your URL actually change but route does not get rendered? Or does the URL remain the same after 1 sec in the address bar? – codemonkey Feb 14 '21 at 23:33

1 Answers1

0
function delay(t, v) {
           return new Promise(function(resolve) { 
               setTimeout(resolve.bind(null, v), t)
           });
        }
        
        
    
    
    auth.createUserWithEmailAndPassword(email, password)
            .then(() => {
                setMessage("Account Created")
                setSuccess(true)
                setLoading(false)
                setTimeout(() => history.push('/'), 1000)

                return delay(1000).then(function() {
                  history.push('/')
                });
            })
            .catch(function (error) {
    
                let errorCode = error.code;
                let errorMessage = error.message;
                if (errorCode) {
                    setError(errorMessage);
                    setLoading(false)
                }
            })

try this code

To keep the promise chain going, you can't use setTimeout() the way you did because you aren't returning a promise from the .then() handler - you're returning it from the setTimeout() callback which does you no good.

using setTimeout on promise chain

selcuk
  • 81
  • 3