Reputation: 833
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
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
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