Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show server-side validation errors after failed form submit

How can I show validation messages after failed form submit? API request returns HTTP 400 'application/problem+json' response and contains violations as a list with field path.

https://www.rfc-editor.org/rfc/rfc7807#section-3

{
   "type": "https://example.net/validation-error",
   "title": "Your request parameters didn't validate.",
   "invalid-params": [ 
      {
         "name": "age",
         "reason": "must be a positive integer"
      },
      {
         "name": "color",
         "reason": "must be 'green', 'red' or 'blue'"
      }
   ]
}
like image 363
Ismail Baskin Avatar asked May 25 '17 22:05

Ismail Baskin


People also ask

How can I see all validation errors in one place?

To display summarized error messagesAdd a ValidationSummary control to the page at the location where you want to display the collected error messages. Set the ErrorMessage and Display properties of the individual validation controls. (Default) Each error message appears as a bulleted item.

How do you stopping form submit if the validation fails?

Use the return value of the function to stop the execution of a form in JavaScript. False would return if the form fails to submit.

Can client-side validation be bypassed?

Client-side validation is executed by the client and can be easily bypassed.


1 Answers

I have the solution for you, I'd recommend to do it with Saga and HttpError.

First, from our dataProvider we need to throw the HttpError like this:

...
import {HttpError} from 'react-admin';
...
...

// Make the request with fetch/axios whatever you prefer and catch the error:
// message - the message that will appear in the alert notification popup
// status - the status code
// errors - the errors in key => value format, example in comment below
return fetchClient.request(config).then((response) => {
      return convertHTTPResponse(response, type, resource, params);
    }).catch(function (error) {
      throw new HttpError(error.response.data.message, error.response.status, error.response.data.errors);
    });

Then create saga like that:

import {CRUD_CREATE_FAILURE} from "react-admin";
import {stopSubmit} from 'redux-form';
import {put, takeEvery} from "redux-saga/effects";

export default function* errorSagas() {
  yield takeEvery(CRUD_CREATE_FAILURE, crudCreateFailure);
}

export function* crudCreateFailure(action) {
  var json = action.payload;
  // json structure looks like this:
  // {
  //     username: "This username is already taken",
  //     age: "Your age must be above 18 years old"
  // }
  yield put(stopSubmit('record-form', json));
}

Please make sure the errors (json) is in the format like in the example above!

Then insert the saga in the componenet:

import errorSagas from './sagas/errorSagas';
...
...

<Admin
        customSagas={[ errorSagas ]}
        loginPage={LoginPage}
        authProvider={authProvider}
        dataProvider={dataProvider}
      >

Boom! it works enter image description here

Good luck!

like image 96
llioor Avatar answered Sep 28 '22 09:09

llioor