By respecting these restrictions,
FP aims to write code that is clearer to understand and more bug resistant.
This is achieved by avoiding using flow-control statements
(for, while, break, continue, goto) which make the code harder to follow.
requires us to
write pure, deterministic
functions which are less likely to be buggy.
//Task 1: Build a function-based console log message generator
function consoleStyler(color, background, fontSize, txt) {
var message = "%c" + txt;
var style = `color: ${color};`;
style += `background: ${background};`;
style += `font-size: ${fontSize};`;
console.log(message, style);
}
// Task 2: Build another console log message generator
function celebrateStyler(reason) {
fontStyle = "color: tomato; font-size: 50px";
if (reason == "birthday") {
console.log(`%cHappy birthday`, fontStyle);
}
else if (reason == "champions") {
console.log(`%cCongrats on the title!`, fontStyle);
}
else {
console.log(message, style);
}
}
// Task 3: Run both the consoleStyler and the celebrateStyler functions
consoleStyler('#1d5c63', '#ede6db', '40px', 'Congrats!')
celebrateStyler('birthday')
// Task 4: Insert a congratulatory and custom message
function styleAndCelebrate(color, background, fontSize, txt, reason) {
consoleStyler(color, background, fontSize, txt);
celebrateStyler(reason);
}
// Call styleAndCelebrate
styleAndCelebrate('ef7c8e', 'fae8e0', '30ox', 'You made it!', 'champions');
const FLAGS = {
minLength: 'MIN-LENGTH',
hasDigit: 'HAS-DIGIT',
}
// Function that handles validation
const validate = (value, flag, validatorValue) => {
switch(flag){
case FLAGS.minLength:
return value.trim().length >= validatorValue
case FLAGS.hasDigit:
return !!value.match(/[0-9]/)
}
}
// Function that sets submit handler
const setFormSubmitHandler = (formId, onSubmit) => {
const form = document.getElementById(formId)
form.addEventListener('submit', onSubmit)
}
// Function that returns values of required fields as object
// In this case it will return {username: "<value>", password: "<value>"}
// It might look scary but keep in mind that it's completely reusable
const getFormValues = (e, ...fields) => {
const values = Object.entries(e.target.elements)
const filteredValues = values.filter(([key]) => fields.includes(key))
return filteredValues.reduce(
(acc, [key, { value }]) => ({ ...acc, [key]: value }),
{}
)
}
// Function that creates valid user
const createUser = (username, password) => {
if (!validate(username, FLAGS.minLength, 3))
throw new Error('Username must be at least 3 characters long')
if (!validate(password, FLAGS.hasDigit))
throw new Error('Password must contain at least one digit')
return { username, password }
}
// Function that creates logger object with *logs* and *showAlert* function
const logger = (() => {
const logs = []
return {
logs,
showAlert: message => {
logs.push(message)
alert(message)
},
}
})()
// Main function
const handleSubmit = e => {
e.preventDefault()
const { username, password } = getFormValues(e, 'username', 'password')
try {
const user = createUser(username, password)
console.log(user)
console.log(logger.logs)
} catch (error) {
logger.showAlert(error)
}
}
setFormSubmitHandler('user-form', handleSubmit)