- camelCase -
/^[a-z]+([A-Z][a-z0-9]+)+/
- kebab-case -
/^[a-z]+([-][a-z0-9]+)+/
- snake_case -
/^[a-z]+([_][a-z0-9]+)+/
- IP Address v4 -
/\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b/
- IP Address v6 -
/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/
- Password -
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})/
- Email -
/^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i
- URL -
/[-a-zA-Z0-9@:%_\+.~#?&\/=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&\/=]*)?/gi
- HTML tag -
/<.+?>/
This hack is optional, but can be used quite frequently to avoid redundant code spamming.
const STATUSES = {
pending: 'Please wait',
approved: 'Your payment has been approved!',
rejected: 'Your payment has been rejected!',
};
const handledStatus = STATUSES[receivedStatus];
Instead of
let handledStatus;
if (receivedStatus === 'pending' {
handledStatus = 'Please wait';
} else if (receivedStatus === 'approved') {
handledStatus = 'Your payment has been approved!';
} else if (receivedStatus === 'rejected') {
handledStatus = 'Your payment has been rejected!';
}
You can even use it with functions to handle extra operations
const STATUSES = {
pending: () => {
toggleLoader(true)
return 'Please wait';
},
approved: () => {
toggleLoader(false);
return 'Your payment has been approved!';
},
rejected: () => {
toggleLoader(false);
return 'Your payment has been rejected!';
},
};
const handledStatus = STATUSES[receivedStatus]();
const status = user?.id ? 'online' : 'offline:
Instead of
let status;
if (user?.id) {
status = 'online';
} else {
status = 'offlne'
}
Instead of
getListOfProducts()
.then(({ data }) => setData(data))
.catch()
Just use
try {
const { data } = await getListOfProducts();
} catch(error) {
...
}
Instead of writing similiar methods again and again just use
import { calculateTotalPrice } from '../utils.js';
Instead of
if (isLoggedIn) {
setLoggedIn(true);
if (isPremium) {
return { premiumStatus: 'activated' };
} else {
return { premiumStatus: 'not_available' };
}
}
Better to use
if (isLoggedIn) {
return isPremium ?
{ premiumStatus: 'activated' } :
{ premiumStatus: 'not_available' };
}
You should extract repetitive parts of the code to the separate functions / classes Instead of
// user.service.js
class UserService {
getUsers() {
return axios.get('http://localhost:4200/api/users',
{headers: {
'Authorization': localStorage.getItem('token'),
}}
)
}
updateUser(user) {
return axios.put('http://localhost:4200/api/users',
user,
{headers: {
'Authorization': localStorage.getItem('token'),
}}
)
}
}
Better to use
The best way to handle that is to create HttpService
class which will be responsible for all the basic things in all services
// http.service.js
import axios from 'axios'; // It could be any fetching services, such as default fetch, call api, xhr, etc.
class HttpSerivce {
constructor(baseUrl = process.env.SERVER_URL, fetchingService = axios, apiVersion = 'api') {
this.baseUrl = baseUrl;
this.fetchingService = axios;
this.apiVersion = apiVersion
}
private getFullApiUrl(url) {
return `${this.baseUrl}/${this.apiVersion}/${url}`;
}
private populateTokenToHeaderConfig() {
return {
'Authorization': localStorage.getItem('token'),
}
}
private extractUrlAndDataFromConfig({data, url, ...configWithoutDataAndUrl}) {
return configWithoutDataAndUrl;
}
get(config, withAuth = true) {
if (withAuth) {
config.headers = {
...config.headers,
...populateTokenToHeaderConfig(),
}
}
return this.fetchingService.get(this.getFullApiUrl(config.url), extractUrlAndDataFromConfig(config));
}
put(config, withAuth = true) {
if (withAuth) {
config.headers = {
...config.headers,
...populateTokenToHeaderConfig(),
}
}
return this.fetchingService.get(this.getFullApiUrl(config.url), config.data, extractUrlAndDataFromConfig(config));
}
}
// user.service.js
import HttpService from './http.service';
class UserService extends HttpSerivce {
constructor() {
super();
}
getUsers() {
return this.get({
url: 'users',
})
}
updateUser(user) {
return this.post({
url: 'users',
data: user,
})
}
Instead of
// user.service.js
class UserService extends HttpSerivce {
constructor() {
super();
}
async getUsers() {
const response = await this.get({
url: 'users',
});
return response.data.map(user => ({
...user,
fullName: user.full_name,
dayOfBirth: new Date(user.dob),
}))
}
}
Better to use
// user.model.js
class UserModel {
constructor(id, fullName, dayOfBirth, status) {
this.id = user.id;
this.fullName = user.full_name;
this.dayOfBirth = new Date(user.dob);
this.status = user.status;
}
getFormatedDayOfBirth() {
return this.dayOfBirth.toDateString();
}
}
const createUserModel = (userFromServer) => {
return new UserModel(userFromServer.id, userFromServer.full_name, userFromServer.dob, userFromServer.status);
};
export {createUserModel};
export default UserModel;
// user.service.js
import { createUserModel } from './user.model';
class UserService extends HttpService {
constructor() {
super();
}
async getUsers() {
const response = await this.get({
url: 'users',
});
return response.data.map(user => createUserModel());
}
}
With that approach you can work with all the data that comes from your server, such as entities. So your code will have better level of abstraction. Also as you see you can attach useful methods to the entity model.
With primitives inside
const unique = [...new Set(array)];
With complex data types;
const removeDuplicates = (array, key) => {
return [...new Map(array.map(item => [item[key], item])).values()]
}
With primitives inside
const difference = biggerArray.filter(x => !smallerArray.includes(x));
With complex data types;
const difference = biggerArray.filter(x => !smallerArray.some(y => y.id === x.id));
const arrayWithFalseValues = ['value_1', 'value_2', 'value_3', null, 'value_4', undefined, 0];
const operateWithFalseValues = (array, type) => {
const excludeFalseValues = array.filter(item => !!item === true);
if (type === 'exclude') {
return excludeFalseValues;
} else {
return excludeFalseValues.length !== array.length;
}
};