1

I have a Register component that sends a POST request to the API and if the registration is successful just show the user a notification and redirect to login page (for now). If not, the server sends back status 400 and a message. When I receive the response, I set a state variable serverError to true and serverMessage to whatever I received from the server to show it to the user.

POST Request logic:

export const registerRequest = (state, setState) => {
  axios.post("api/auth/register", {
   "email": state.email, "password": state.password, "firstName": state.firstName, "lastName": state.lastName
    }).then((response) => {
        if (response.status === 200) {
            setState({
                ...state,
                serverError: false
            });
        }
    }).catch((exception) => {
        setState({
            ...state,
            serverMessage: exception.response.data,
            serverError: true,
        });
    });
}

First I tried doing this "show user what's wrong" in the function dealing with form submit but I kept getting serverError === true but serverMessage being equal to an empty string (as declared in state). So next I tried using a componentDidUpdate equivalent in useEffect with the required dependencies and didMount useRef hook to make sure I show the notification only after the component is updated (i.e. after state update). Didn't work either.

useEffect and handleSubmit hook/function (useHistory is from react-router-dom and Notification is an antD component that takes a title and a description):

const { serverError, serverMessage } = state;
const didMountRef = useRef(false);

useEffect(() => {
    if (didMountRef.current) {
        if (serverError) {
            StyleImports.Notification["success"]({
                message: [JsonImports.registerNotificationSuccess],
                description: [JsonImports.registerSuccessDetails]
            });
            setTimeout(() => { history.push("/"); }, 4.5 * 1000);
        }
        else {
            StyleImports.Notification["error"]({
                message: [JsonImports.registerNotificationFail],
                description: serverMessage
            });
        }
    }
    else didMountRef.current = true;
    
}, [serverError, serverMessage, history]);


const handleSubmit = (event) => {
    // just some form validation logic before form submission
    event.preventDefault();
    registerRequest(state, setState);
    // commented just to show you what I did initially
    /*if (state.serverError) {
        StyleImports.Notification["success"]({
            message: [JsonImports.registerNotificationSuccess],
            description: [JsonImports.registerSuccessDetails]
        });
        setTimeout(() => { history.push("/"); }, 4.5 * 1000);
    }
    else {
        StyleImports.Notification["error"]({
            message: [JsonImports.registerNotificationFail],
            description: state.serverMessage
        });
    }*/
}

Any ideas on how to handle this properly? Just showing some message declared in a JSON client-side is not a good idea in my opinion since I can get different messages from the server. I guess setState didn't actually update serverMessage since it's a pretty big string and would take more time?

1 Answers1

1

It depends what kind of error you have and what message you get from your backend.

First i would suggest to debug your exception property and have a look what data is available. Just set a breakpoint at the setState({ line or add a console.log(error) before this line. Please inspect whats inside your exception.

After this you can handle the different error cases e.g.:

...
.catch(function (error) {
    if (error.response) {
      // Request made and server responded
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // The request was made but no response was received
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }

or maybe this fits your data? It all depends to what is inside your error

  .catch(error => {
     console.log(error.response.data.error)
  })

Please have a look the axios-handling-errors thread too.

BTW this looks like a bug? serverError is maybe no success ;-)

if (serverError) {
            StyleImports.Notification["success"]({
zerocewl
  • 11,401
  • 6
  • 27
  • 53
  • Yeah, that would be it. I didn't focus on that at all, I thought there was something wrong with my logic. Thanks. – Liviu Ganea Jul 29 '21 at 06:11