DEV Community

Cover image for Javascript Tricks
Edison Sanchez
Edison Sanchez

Posted on • Edited on

Javascript Tricks

How to check null value and undefined to get a nested object's property?

nullish and chain operators

 const product = { name: 'Coke', price: 10, provider: { name: 'Wailkk', address: 'Fake Street', state: { id: 1, name: 'Florida', country: { code: 'US', name: 'United States', }, }, orders: null, fPrice: (x) => 100, }, }; //Old way const providerCountry = product.provider ? product.provider.name ? product.provider.name : null : null; //Nullish Coalsencing Operator Way //If the value is null then this option it will not works. const _providerCountry = product.provider.name ?? undefined; //Not work if the value is null const providerOrders = product.provider.orders ?? 1; // Should be null. [Error] // Nullish not defined. const providerNotDefined = product.provider.notDefined ?? null; //Trick: chaining Operator const providerAddress = product?.provider?.address; //It works with Dynamic properties. const propertyName = 'price'; const productPrice = product?.[propertyName]?.explore; 
Enter fullscreen mode Exit fullscreen mode

Chain Operator Way

If a property doesn't exist or value is undefined then will returns undefined, keeping your code clean. If a property doesn't exist undefined will be returned. Let's see how this operator looks with the same example object:

 //Trick: chaining Operator const providerAddress = product?.provider?.address; //It works with Dynamic properties. const propertyName = 'price'; const productPrice = product?.[propertyName]?.explore; //Works with Functions too. const productProviderPrice = product?.provider?.fPrice?.('x'); //Result: 100; const _productProviderPrice = product?.provider?.fPricex?.('x'); //Result: undefined 
Enter fullscreen mode Exit fullscreen mode

NOT Compatible with: Internet Explorer, Firefox for Android, Opera for Android, and Samsung Internet Browser.


IIFE: Immediately-Invoked Function Expression

It's a function invoked immediately after it is defined (as the name says).

let hi = (() => { return 'Hello Dear World'; })(); //Define function and parenthesis before the semicolon. console.log(hi); // Result = 'Hello Dear World' 
Enter fullscreen mode Exit fullscreen mode

Function Closures

Combination of functions stacked or bundled together with access over outer layers or outer function's scope.

const functionLevelOne = () => { let day = 23; const functionLevelTwo = () => { day += 1; return day; } return functionLevelTwo; } console.log(functionLevelOne()); // Result: 24; // It's calling the return function on level one. 
Enter fullscreen mode Exit fullscreen mode

When to use spread operators?

Merge two arrays using spreads could impact on performance if it's a repetitive call. And if we call a function passing arguments like spread and that call is frequently. Use ...spread only when it's not a repetitive call or for a function's call but not as argument spread definition.

I will keep adding and updating tricks to this article frequently.

Find and Filtering

  • Find a record for key value:
let colors = [ { id: 0, color: 'Red' }, { id: 1, color: 'Green' }, { id: 2, color: 'Blue' } ]; let greenColor = colors.find(color => color.color === 'Green'); 
Enter fullscreen mode Exit fullscreen mode

Filter Records by id value

let users = [ { id: 0, name: 'John Smith' }, { id: 1, name: 'Mary Smith' }, { id: 2, name: 'Jane Foster' } ]; let filteredData = data.filter(path => path.includes('Smith')); 
Enter fullscreen mode Exit fullscreen mode

Returns the name of users with the last name 'Smith'.

Iterations

Iterate between key,values for an object.

let myObject = { one: 1, two: 2, three: 3 }; Object.keys(myObject).forEach((key, value) => { //...do something console.log(key, value); }); 
Enter fullscreen mode Exit fullscreen mode

Event Loop Essentials.

A Task queue is used by Javascript. Javascript tasks have the highest priority. Micro Tasks like promises have the second priority position; third place for Macro Tasks executed before (requestAnimationFrame) or after (setTimeout) to render.

console.log(1); Promise.resolve().then(() => console.log(2)); setTimeout(() => console.log(3), 100); console.log(4); // 1 -> 4 -> 2 -> 3 
Enter fullscreen mode Exit fullscreen mode

There are three ways to add your callback function(s) to the DOM element as the event callback.

  • InLine (Higher Priority)

    <div onclick="console.log('div')">Hello</div> 
  • Bind Callback (Medium Priority)

    div.onclick = () => console.log('div'); 
  • Add/Remove Event Listener: Supports Multiple Callbacks associated with the same event. Supports Event bubbling and capturing.

    div.addEventListener('click', callbackOne); div.removeEventListener(callbackOne); 

Bubbling

<div onclick="console.log('div')"> <p onclick="console.log('p')"> <span onclick="console.log('span')"> </span>  </p> </div> //span → p → div 
Enter fullscreen mode Exit fullscreen mode

Bubbling: The innermost element → the second innermost element → … → the outermost element
Capturing: The outermost element → the second outermost element → … → the innermost element

Capturing is triggered earlier than bubbling

div.addEventListener('click', () => console.log('div')); p.addEventListener('click', () => console.log('p'), { capture: true }); span.addEventListener('click', () => console.log('span')); //Result: p → span → div 
Enter fullscreen mode Exit fullscreen mode

div and span use bubbling, and p uses capturing.

Event Delegation

If you have a loop function with multiple callbacks that will affects the performance:

const ul = document.getElementById('myUL'); for (let i = 0; i < 100; i += 1) { const li = document.createElement('li'); li.textContent = `li-${i}`; li.id = `li-${i}`; li.addEventListener('click', e => console.log(e.target.id)); ul.appendChild(li); } 
Enter fullscreen mode Exit fullscreen mode

Delegate one callback for all.

const ul = document.getElementById('myUL'); for (let i = 0; i < 100; i += 1) { const li = document.createElement('li'); li.textContent = `li-${i}`; li.id = `li-${i}`; ul.appendChild(li); } ul.addEventListener('click', e => console.log(e.target.id)); 
Enter fullscreen mode Exit fullscreen mode

Event Propagation

Stop propagation makes a halt to the propagation used by bubbling or capturing.

div.addEventListener('click', () => console.log('div'), true); p.addEventListener('click', e => { e.stopPropagation(); console.log('p'); }); span.addEventListener('click', () => console.log('span'), true); 
Enter fullscreen mode Exit fullscreen mode

When user clicks

only will be logged 'p'.

XMLHttpRequest

Oldest fetch data in an asynchronous way

const oReq = new XMLHttpRequest(); oReq.open('GET', 'https://jsonplaceholder.typicode.com/todos/1'); oReq.send(); oReq.addEventListener('load', function () { console.log(this.responeText); }); 
Enter fullscreen mode Exit fullscreen mode

Fetch

New way with more options than XMLHttpRequest, returns a promise

// Promise fetch(url) .then(res => res.json()) .then(data => console.log(data)); // async & await const res = await fetch(url); const data = await res.json(); console.log(data); 
Enter fullscreen mode Exit fullscreen mode

Axios

It takes the best of XMLHttpRequest and fetch.

// Promise  axios.get('/user?ID=12345') .then(function (response) { // handle success console.log(response); }) .catch(function (error) { // handle error console.log(error); }) .finally(function () { // always executed }); // async & await async function getUser() { try { const response = await axios.get('/user?ID=12345'); console.log(response); } catch (error) { console.error(error); } } 
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
jonrandy profile image
Jon Randy 🎖️

Your "Function Closures" example returns the functionLevelTwo function, not 24