Rad80
Rad80

Reputation: 833

Use server-side validation response in react-admin

In my app using react-admin I have a few forms where the validation must be performed on the server side. My API (implemented with api-platform) returns a 400 response with a key in its body that contains an array of the constraint violations, keyed to the field names, so the information is there to provide field-by-field error messages.

This issue is the same explored in this old question. However, since react-admin moved from redux-form to react-final-form, solutions based on an error saga do not work anymore.

The example given in the official react-final-form docs is not easy to apply because react-admin manages the onSubmit property by itself.

Upvotes: 7

Views: 1131

Answers (2)

Vishnu Prasad
Vishnu Prasad

Reputation: 330

React admin is purely client based application, i understood your concern. You need to run a node server and inside the node server run the react admin.

please have a look https://www.twilio.com/blog/react-app-with-node-js-server-proxy

You can mention a specific route and run your node script for server validation .

Upvotes: -2

Jeremy Bunn
Jeremy Bunn

Reputation: 671

So relieve! I was thinking there was no server side validation for RA in the 3.x base. Not true!

Found a working solution for react-admin 3.8.1 that seems to work well.

Here is the reference code and example. It works!! Note: Replace the server side validation with your own. I have used react-admin validation with YUP server side validation following this pattern.

Also, you can use validate at the SimpleForm level to do whole form validation. This example is for a single field but they both work.

https://codesandbox.io/s/wy7z7q5zx5?file=/index.js:966-979

Example:

First make the helper functions as necessary for the example

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const simpleMemoize = fn => {
  let lastArg;
  let lastResult;
  return arg => {
    if (arg !== lastArg) {
      lastArg = arg;
      lastResult = fn(arg);
    }
    return lastResult;
  };
};

Then the actual validation code

const usernameAvailable = simpleMemoize(async value => {
  if (!value) {
    return "Required";
  }
  await sleep(400);
  if (
    ~["john", "paul", "george", "ringo"].indexOf(value && value.toLowerCase())
  ) {
    return "Username taken!";
  }
});

Finally wire it up to your field:

const validateUserName = [required(), maxLength(10), abbrevUnique];

const UserNameInput = (props) => {
    return (
        <TextInput
            label="User Name"
            source="username"
            variant='outlined'
            validate={validateAbbrev}
        >
        </TextInput>);
}

Upvotes: 3

Related Questions