Use server-side validation response in react-admin
Asked Answered
M

2

7

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.

Myxoma answered 6/2, 2020 at 14:47 Comment(1)
Running into the same issue with our app. Upgrading from react-admin 2.9 --> 3+ broke how we show server side validation errors on the form.Marzipan
X
3

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>);
}
Xanthus answered 23/8, 2020 at 17:52 Comment(1)
Could you provide an example for full form validation? I'm not tracking how to do this after submitting the formVillalba
H
-2

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 .

Habited answered 19/8, 2020 at 21:20 Comment(1)
I know that and my application does have a server-side part (not written in JS). The issue is that when the server-side validation fails there is no way to present the violations clearly to the user (if you need a use case, think of a uniqueness constraint that cannot be checked client-side).Myxoma

© 2022 - 2024 — McMap. All rights reserved.