From da4dfe5ec3a6540e3e54a8140eb2590ffd17f366 Mon Sep 17 00:00:00 2001 From: Mathieu Puech Date: Fri, 26 Feb 2021 18:09:17 -0500 Subject: [PATCH] docs(validation): add backend validator example --- .../docs/17-validation-examples.md | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/packages/form-integrations/docs/17-validation-examples.md b/packages/form-integrations/docs/17-validation-examples.md index 200c328d6..3e554134c 100644 --- a/packages/form-integrations/docs/17-validation-examples.md +++ b/packages/form-integrations/docs/17-validation-examples.md @@ -695,3 +695,92 @@ export const FormValidationReset = () => html` `; ``` + +## 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` + + +
+ + + + + Submit +
+
+ `; +}; +```