Merge pull request #1248 from ing-bank/docs/addBackendValidationExample

docs(validation): add backend validator example
This commit is contained in:
Mathieu Puech 2021-03-01 11:45:00 -05:00 committed by GitHub
commit 155b0cda4e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -695,3 +695,92 @@ export const FormValidationReset = () => html`
</lion-form>
`;
```
## Backend validation
Backend validation is needed in some cases. For example, you have a sign up form, the username could be already taken. You can add an `AsyncValidator` to check the availability when the `username` field is changed but you may have a conflict when you submit the form (another user take the username in parallel).
```js preview-story
export const backendValidation = () => {
// Mock
function fakeFetch(ms = 0, withError = false) {
return new Promise(resolve => {
setTimeout(() => {
resolve(
new Response(
JSON.stringify({
message: withError ? 'Username is already taken' : '',
}),
{ status: withError ? 400 : 200 },
),
);
}, ms);
});
}
let backendValidationResolver;
let backendErrorMessage = 'Unknown Error';
let isBackendCallPending = false;
const submitHandler = ev => {
const lionForm = ev.target;
if (lionForm.hasFeedbackFor.includes('error')) {
const firstFormElWithError = lionForm.formElements.find(el =>
el.hasFeedbackFor.includes('error'),
);
firstFormElWithError.focus();
return;
}
isBackendCallPending = true;
lionForm.formElements.username.validate(); // => backendValidationResolver will be assigned
const formData = lionForm.serializedValue;
fakeFetch(2000, formData.simulateError.length).then(async response => {
if (response.status !== 200) {
backendErrorMessage = (await response.json())?.message;
backendValidationResolver(true);
}
backendValidationResolver(false);
isBackendCallPending = false;
});
};
class BackendValidator extends Validator {
static get validatorName() {
return 'backendValidator';
}
static get async() {
return true;
}
async execute() {
if (isBackendCallPending) {
return await new Promise(resolve => (backendValidationResolver = resolve));
}
return false;
}
static getMessage({ fieldName, modelValue, params: param }) {
return backendErrorMessage;
}
}
return html`
<style>
lion-input[is-pending] {
opacity: 0.5;
}
</style>
<lion-form @submit=${submitHandler}>
<form>
<lion-input
label="username"
name="username"
.validators="${[new BackendValidator(''), new Required()]}"
.modelValue="${''}"
></lion-input>
<lion-checkbox-group name="simulateError">
<lion-checkbox label="Check to simulate a backend error"></lion-checkbox>
</lion-checkbox-group>
<lion-button raised>Submit</lion-button>
</form>
</lion-form>
`;
};
```