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.
Client Side Validation using FormValidator in React TimePicker component. To achieve the client side validation in a TimePicker component by using Essential JavaScript 2 FormValidator. It provides an option to customize the feedback error messages to the corresponding fields to take action to resolve the issue.
In the Server Side Validation, the input submitted by the user is being sent to the server and validated using one of server side scripting languages such as ASP.Net, PHP etc. After the validation process on the Server Side, the feedback is sent back to the client by a new dynamically generated web page.
It depends on what you understand by "_ work on server side instead of client side_". If by the above you understand moving validation to server side, then yes, it is definitely possible.
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>);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With