Skip to content

Instantly share code, notes, and snippets.

@ekrem-aktas
Last active April 29, 2023 14:43
Show Gist options
  • Save ekrem-aktas/597d188578a61f491fe3c61b5cd28b5f to your computer and use it in GitHub Desktop.
Save ekrem-aktas/597d188578a61f491fe3c61b5cd28b5f to your computer and use it in GitHub Desktop.
// Returns a function which runs given checkFn against a value.
const createRule = (checkFn, errorMessage) => {
return async (value) => await Promise.resolve(checkFn(value)) ? null : errorMessage;
}
// Returns a function which accepts a value to validate and runs all passed rules.
const defineValidator = (...rules) => {
return async (value) => {
for (const rule of rules) {
const errorMessage = await rule(value);
if (errorMessage !== null) {
return { valid: false, reason: errorMessage };
}
}
return { valid: true, reason: null };
}
}
// Define rules
const validNonEmptyString = (value) => typeof value === "string" && value.trim() !== "";
const validUsername = (username) => username.match(/^\w+$/);
const isUniqueUsername = async (username) => {
const response = await fetch(`/api/checkusername/${username}`); // returns { available: true | false }
return (await response.json()).available;
}
// Define a validator combining various rules
const validateUsername = defineValidator(
createRule(validNonEmptyString, "Username is needed"),
createRule(validUsername, "Username must consist of characters and numbers"),
createRule(isUniqueUsername, "Username is already taken")
);
const showError = (text) => {
document.getElementById("error-text").innerText = text;
}
// Use it.
validateUsername("test").then(({ valid, reason }) => {
if (!valid) {
showError(reason);
return;
}
// continue with registration
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment