Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 21, 2021 09:27 am GMT

10 tips to improve readability in Javascript

1. Log level and semantic methods

Console docs

console.log("hello world")console.warn("this is a warning")console.error("this is an error")console.info("this is info")console.debug("this is debug")console.trace("show trace")

If you try the console.warn, you will get the trace which means that it is easier to debug the code

Let's try other console functions yourself :)

Original code

console.log("Error: API key should not be empty")

Refactor

console.error("Error: API key should not be empty")

2. Avoid negative names for boolean variables

It is hard to read double negatives

isStarted isNotStarted

Original code

const isInvalidApiKey = apiKey === nullif (isInvalidApiKey) {}

Refactor

const isValidApiKey = apiKey != nullif (!isValidApiKey) {}

3. Avoid flag params

You don't know what the flag params are used for util you have to read the function declaration

Original code

renderResult(true)function renderResult(isAuthenticated) {    if (isAuthenticated) {       return <p>App</p>    } else {        return <p>Please login</p>    }}

Use object params

renderResult({isAuthenticated: true})function renderResult({isAuthenticated}) {    if (isAuthenticated) {        return <p>App</p>    } else {        return <p>Please login</p>    }}

Use 2 functions

function renderAuthenticatedApp() {    return <p>App</p>}function renderUnAuthenticatedApp() {    return <p>Please login</p>}

4. Use guard clauses

Nesting hell

Make our code fail fast
Natural flow

if (statusCode === 200) {    // success} else {    if (statusCode === 500) {        // Internal Server Error    } else if (statusCode === 400) {        // Not Found    } else {        // Other error    }}
if (statusCode === 500) {    // Internal Server Error}if (statusCode === 400) {    // Not Found}if (statusCode !== 200) {    // Other error}// success

5. Make code self-explanatory

Easy to understand
Reusable
A long descriptive name is better than a long comment

// verify that user has added a credit cardfunction verify(user) {}
function verifyThatUserHasAddedCreditCard(user) {}

Original code

 if (country !== 'finland' &&    country !== 'germany' &&    country !== 'vietnam' &&    country !== 'russia' &&    type !== '') {    return Promise.reject('Not available')}

Refactor

const isInAvailableCountries = (    country === 'finland' ||    country === 'germany' ||    country === 'vietnam' ||    country === 'russia')const hasBoom = type === ''if (!isInAvailableCountries || hasBoom) {    return Promise.reject('Not available')}

Create a better condition

const availableCountries = ['finland', 'germany', 'vietnam', 'russia']const isInAvailableCountries = availableCountries.includes(country)const hasBoom = type === ''if (!isInAvailableCountries || hasBoom) {    return Promise.reject('Not available')}

6. Make impossible states impossible

Easy to understand

Prevent lots of bugs

Stop using isLoading booleans

isLoading: trueisError: falseisLoading: falseisError: true// imposible statesisLoading: trueisError: trueisLoading: falseisError: false
const LOADING_STATE = 'LOADING_STATE'const ERROR_STATE = 'ERROR_STATE'const state = LOADING_STATE

Original code

const [isLoading, setIsLoading] = React.useState(false)const [error, setError] = React.useState(null)const [coffee, setCoffee] = React.useState(null)function handleButtonClick() {    setIsLoading(true)    setError(null)    setCoffee(null)    getCoffee('cappuccino', 'small', 'finland', true).then(coffee => {        setIsLoading(false)        setError(null)        setCoffee(coffee)    }).catch(error => {        setIsLoading(false)        setError(error)    })}

Refactor

const state = {    idle: 'idle',    loading: 'loading',    error: 'error',    success: 'success',}const [error, setError] = React.useState(null)const [coffee, setCoffee] = React.useState(null)const [status, setStatus] = React.useState(state.idle) function handleButtonClick() {    setStatus(state.loading)    getCoffee('cappuccino', 'small', 'finland', true).then(coffee => {        setStatus(state.success)        setCoffee(coffee)    }).catch(error => {        setStatus(state.error)        setError(error)    })}

7. Use objects for long argument lists

Params order won't matter

Easy to pass optional param

function getBox(type, size, price, color) {}getBox('carry', undefined, 10, 'red')
function getBox(options) {    const {type, size, price, color} = options}getBox({    type: 'carry',    price: 10,    color: 'red'})

Original code

export function getCoffee(type, size, country, hasIce) {getCoffee('cappuccino', 'small', 'finland', true)}

Refactor

function getCoffee(options) {    const {type, size, country, hasIce} = options}getCoffee({    type: 'cappuccino',    size: 'small',    country: 'finland',    hasIce: true})

8. Use Object.assign for defaults

function getBox(options) {    options.type = options.type || 'carry'    options.size = options.size || 'small'    options.price = options.price || 10    options.color = options.color || 'red'    const {type, size, price, color} = options}
function getBox(customOptions) {    const defaults = {        type: 'carry',        size: 'small',        price: 10,        color: 'red',    }    const options = Object.assign(defaults, customOptions)    const {type, size, price, color} = options}

Original code

export function getCoffee(type, size, country, hasIce) {    type = type || 'cappuccino'    size = size || 'small'    country = country || 'finland'    hasIce = hasIce || false}

Refactor

function getCoffee(customOptions) {    const defaultOptions = {        type: 'cappuccino',        size: 'small',        country: 'finland',        hasIce: false    }    const options = Object.assign(defaultOptions, customOptions)}function getCoffee(options = {}) {    const {        type = 'cappuccino',        size = 'small',        country = 'finland',        hasIce = false    } = options}function getCoffee({    type = 'cappuccino',     size = 'small',    country = 'finland',    hasIce = false} = {}) {}

9. Replacing switch statements with Object literals

Replacing switch statements with Object literals

const handleSaveCalculation = ({key}) => {    switch (key) {        case 'save-copy': {            saveCopy()            break        }        case 'override': {            override()            break        }        default:            throw Error('Unknown action')    }}handleSaveCalculation({key: 'save-copy'})
const handleSaveCalculation = ({key}) => {    const actions = {        'save-copy': saveCopy,        'override': override,        'default': () => throw Error('Unknown action')    }    const action = key in actions ? actions[key] : actions['default']    return action();}handleSaveCalculation({key: 'save-copy'})

Original code

let drinkswitch(type) {    case 'cappuccino':        drink = 'Cappuccino';        break;    case 'flatWhite':        drink = 'Flat White';        break;    case 'espresso':        drink = 'Espresso';        break;    default:        drink = 'Unknown drink';}

Refactor

const menu = {    'cappuccino': 'Cappuccino',    'flatWhite': 'Flat White',    'espresso': 'Espresso',    'default': 'Unknown drink'}const drink = menu[type] || menu['default']

10. Avoid Hasty Abstractions

I don't know how to create a good abstraction but I've created many bad ones

prefer duplication over the wrong abstraction

Nothing is free. The code trades the ability to change requirements for reduced duplication, and it is not a good trade - Dan Abramov

AHA Programming

Goodbye, Clean Code

My React Boilerplate

The code below is used to fetch an order and I am using Redux for the state management. What a boilerplate!!! Let's make an abstraction which I will regret later

Fetch an order

// Action Typeconst FETCH_ORDERS_START = "FETCH_ORDERS_START";const FETCH_ORDERS_SUCCESS = "FETCH_ORDERS_SUCCESS";const FETCH_ORDERS_FAILED = "FETCH_ORDERS_FAILED";
// Actionexport const fetchOrder = (token) => {    return dispatch => {        dispatch(fetchOrdersStart);        axios.get('/orders.json?auth=' + token).then(res => {            dispatch(fetchOrdersSuccess(res));        }).catch(err => {            dispatch(fetchOrdersFailed(err));        });    };}export const fetchOrdersSuccess = (orders) => {    return {        type: FETCH_ORDERS_SUCCESS,        orders: orders,    };};export const fetchOrdersFailed = (error) => {    return {        type: FETCH_ORDERS_FAILED,        error: error,    };};export const fetchOrdersStart = () => {    return {        type: FETCH_ORDERS_START,    };};

Abstraction

I dare you understand the abstraction code without clicking the link. And even go to that link, you have to read all the code to understand that abstraction.

If you want to take a deep look into this, checkout AHA Programming and Goodbye, Clean Code

// Actionconst moduleName = 'order'const path = '/order'const {moduleActionTypes, moduleActions} = useModuleActions(moduleName, path)function fetchOrder() {    moduleActionTypes.getModel()    }function updateOrder(data) {    moduleActionTypes.updateModel(data)}

Resource

Github


Original Link: https://dev.to/dinhhuyams/10-tips-to-improve-readability-in-javascript-53a3

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To