skip to Main Content

I have a registration form that after submission of which I want to navigate to other screen only if the request succeeds in the action file not in Component itself.

I’m sending navigation as an argument to the function from my component but the navigation is not happening.

Any suggestions about this issue?

// Action.js
export const registerUser = (formData, navigation) => async dispatch => {
  try {
    const response = await axios.post(`${config.END_POINT}/users`, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })

    await AsyncStorage.setItem('token', response.data.token)

    dispatch({ type: 'auth/setToken' })

    loadUser(navigation)
  } catch (error) {
    console.error(error.message)
  }
}
export const loadUser = (navigation) => async dispatch => {
  try {
    const response = await axios.get(`${config.END_POINT}/auth`)

    dispatch({
      type: 'auth/setUser',
      payload: response.data
    })

    navigation.navigate('Home')
  } catch (error) {
    console.error(error.message)
  }
}

In component.js after filling form

dispatch(registerUser(formData, navigation))

2

Answers


  1. loadUser appears to be another asynchronous action creator. loadUser is a function that takes a navigation argument and returns another function that needs to also be called in order for that function body to be executed and the navigation action effected. The registerUser action calls loadUser(navigation) but then never calls the returned function.

    In other words, loadUser(navigation) returns the following

    async dispatch => {
      try {
        const response = await axios.get(`${config.END_POINT}/auth`);
    
        dispatch({
          type: 'auth/setUser',
          payload: response.data
        });
    
        navigation.navigate('Home');
      } catch (error) {
        console.error(error.message);
      }
    };
    

    This function is never called.

    You should dispatch this loadUser action so the thunk/asynchronous middleware can call the function and again pass dispatch to it.

    Example:

    export const registerUser = (formData, navigation) => async dispatch => {
      try {
        const response = await axios.post(
          `${config.END_POINT}/users`,
          formData, {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          }
        );
    
        await AsyncStorage.setItem('token', response.data.token);
    
        dispatch({ type: 'auth/setToken' });
    
        dispatch(loadUser(navigation)); // <-- dispatch action!
      } catch (error) {
        console.error(error.message);
      }
    };
    
    Login or Signup to reply.
  2. you are calling the loadUser function from the registerUser action after a successful registration. However, the loadUser function is asynchronous, meaning that it does not immediately return a value. Therefore, the navigation call after loadUser will not wait for the loadUser function to complete before navigating.

    To make sure that the navigation only happens after loadUser has completed successfully, you can modify the registerUser action to return a promise that resolves when loadUser is done. Here’s how you can modify the registerUser action:

    export const registerUser = (formData, navigation) => async dispatch => {
      try {
        const response = await axios.post(`${config.END_POINT}/users`, formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        })
    
        await AsyncStorage.setItem('token', response.data.token)
    
        dispatch({ type: 'auth/setToken' })
    
        await dispatch(loadUser(navigation)) // Wait for loadUser to complete
    
      } catch (error) {
        console.error(error.message)
      }
    }
    

    By await-ing the dispatch call to loadUser, the navigation will only happen after loadUser has completed successfully. Also, make sure that you return the loadUser call from the loadUser function so that it can be await-ed in the registerUser action.

    export const loadUser = (navigation) => async dispatch => {
      try {
        const response = await axios.get(`${config.END_POINT}/auth`)
    
        dispatch({
          type: 'auth/setUser',
          payload: response.data
        })
    
        navigation.navigate('Home')
    
        return true // Return a value to indicate success
    
      } catch (error) {
        console.error(error.message)
    
        return false // Return a value to indicate failure
      }
    }
    

    With these changes, the registerUser action should now return a promise that resolves when the loadUser function completes, and the navigation should only happen after the loadUser function has completed successfully.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search