20 posts about #javascript

Import SVGs as components in webpack

Install svgr:

npm install --save-dev @svgr/webpack

Add an import rule for svgs:

module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/i,
        use: ['@svgr/webpack'],
      },
    ],
  },
}

Voilà!

import Star from './star.svg'

const Example = () => (
  <div>
    <Star />
  </div>
)

Use isSameorAfter to set condition to select specific periods

momentjs is a JavaScript library that helps parse, validate, manipulate, and display date/time in JavaScript in a very easy way.

momentjs provide specific instructions to handle dates which can create conditions in each one, to select a period after and same that you needed, like a >= instruction use isSameorAfter:

moment('2010-10-20').isSameOrAfter('2010-10-19'); // true
moment('2010-10-20').isSameOrAfter('2010-10-20'); // true
moment('2010-10-20').isSameOrAfter('2010-10-21'); // false

How to use object destructuring with the index over an array?

const names = ['Roy', 'Liz', 'Sofia', 'Clau']

const {
  0: zero,
  1: one,
  2: two,
  3: three,
} = names

console.log(zero) // 'Roy'

Use the spread syntax to find what an emoji is made up of

Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected. [1]

[1] Source: MDN Web Docs

[...'👨‍🎤']
(3) ['👨', '', '🎤']0: "👨"1: ""2: "🎤"length: 3[[Prototype]]: Array(0)
[...'🧟']
['🧟']
[...'👩‍👩‍👧‍👧']
(7) ['👩', '', '👩', '', '👧', '', '👧']

Learned from @mgechev at https://twitter.com/mgechev/status/1490920854313648128/photo/1

Useful? not sure

Interesting? Hell yeah!

Sort an array of objects by a property value

Imagine that we have the next object:

const names = [
  { name: 'Sam', lastName: 'Belmor'},
  { name: 'Yasser', lastName: 'Velasco' },
  { name: 'Ayrton', lastName: 'Morales' }
]

If we wanna sort those values alpabethically by name we could do this:

names.sort((a, b) => (a.name > b.name) ? 1 : -1)

We'll have this result:

[
  { name: 'Ayrton', lastName: 'Morales' },
  { name: 'Sam', lastName: 'Belmor' },
  { name: 'Yasser', lastName: 'Velasco' }
]

If return 1, the function communicates to sort() that the object b takes precedence in sorting over the object a. Returning -1 would do the opposite.

.forEach .map() loop JavaScript

For Each .forEach iterates the elements of an array but does not return a value.

const a = [1, 2, 3];
const newArray = a.forEach((num, index) => {
  //do something 
});

// newArray = undefined

Map .map iterates the elements of an array but return a new array.

const a = [1, 2, 3];
const newArray = a.map(num => {
  return num * 2;
});

// newArray = [2, 4, 6]

Numberic separators JavaScript

Numberic separators is a new JavaScript feature that allows you to use underscores as separators to help to improve readability using a visual separation between groups of digits.

// A billion
const amount = 1_000_000_000;

// Hundreds of millions     
const amount = 1_475_938.38;

// 6234500 cents (62345 dollars)
const amount = 62345_00;

// 1,734,500
const amount = 1_734_500; 

// 20^30000
const amount = 2e30_000;

Javascript event loop

The event loop is the secret behind JavaScript's asynchronous programming. JS executes all operations on a single thread, but using a few smart data structures, it gives us the illusion of multi-threading but first we have to understand the Call Stack.

Call Stack

The call stack works based on the LIFO principle(last in first out) When you execute a script, the JavaScript engine creates a Global Execution Context and pushes it on top of the call stack.

function multiply(a, b) {
    return a * b
}

function squere(n) {
    return multiply(n, n)
}

function printSquere(n) {
    var result = squere(n)
    console.log(result)
}

printSquere(4)

**Stack**
4- multiply
3- squere
2- printSquere
1- main

Result: 16

Call Stack with async callbacks (Even loop)

The event loop facilitates this process; it constantly checks whether or not the call stack is empty. If it is empty, new functions are added from the event queue. If it is not, then the current function call is processed.

An example of this is the setTimeout method. When a setTimeout operation is processed in the stack, it is sent to the corresponding API which waits till the specified time to send this operation back in for processing.

console.log('hi')

setTimeout(()=> {
  console.log('there')
},5000)

console.log('bye')

**Stack**
3- there
2- bye
1- hi

**webapis**
setTimeout callback(cb)

**taskqueue**
callback(cb)

**evenloop**
move cb to stack

In the example the setTimeout Callback enters the webapi stack executes and then goes to the task queue and waits for the stack to become empty and the event loop moves the callback to the stack.

Truthy and Falsy Values

If JavaScript's built-in type coercion makes it true, thats mean that the values is a truthy.

  true
  {}
  []
  42
  "0"
  "false"
  new Date()
  -42
  12n
  3.14
  Infinity
  -Infinity

and in Javascript a falsy value is a value that is considered false

  false
  0
  0n: 0 as a BigInt
  '': Empty string
  null
  undefined
  NaN

Javascript Hoisting

This means that variable and function declarations are physically moved to the beginning of the code and are allocated in memory during the compilation phase.

function welcomeTo(name) {
  console.log("Welcome to " + name);
}

welcomeTo("Magmalabs");
//returns welcome to magmalabs

As you can see hoisting allows you to use a function before declaring it in the code.

welcomeTo("Magmalabs");

function welcomeTo(name) {
  console.log("Welcome to " + name);
}
//returns welcome to magmalabs

And also allows you to use a function after declaring it in the code.

For variables, hoisting only applies to the declaration, not to their assignment. example:

We declare the variable name but we got an undefined

console.log(name); 
var name = magmalabs;
//return undefined

That’s because JavaScript only hoist the declaration

var name;

console.log(name); 
name = magmalabs;
//return undefined

To avoid these errors, it is very important to keep in mind that hoisting only applies to the declaration.

Browsers' IndexedDB are shared across domain

I was working on a major refactor for a PWA which basically changed the DB schema by reducing the amount of versions, nothing outstanding. BUT, I didn't change the DB name.

I was puzzled why whenever accessing the previous version I had to delete the data to have the app load correctly, then I realized that despite the PWA being located at different URL paths, both versions were using the same IndexedDB because of the same domain policy.

NIX node manager

Use n, an extremely simple Node version manager that can be installed via npm.

Say you want Node.js v12.10.0 to build Ghost template.

npm install -g n   # Install n globally
n 12.10.0          # Install and use v12.10.0
Usage:
n                            # Output versions installed
n latest                     # Install or activate the latest node release
n stable                     # Install or activate the latest stable node release
n <version>                  # Install node <version>
n use <version> [args ...]   # Execute node <version> with [args ...]
n bin <version>              # Output bin path for <version>
n rm <version ...>           # Remove the given version(s)
n --latest                   # Output the latest node version available
n --stable                   # Output the latest stable node version available
n ls                         # Output the versions of node available

Optional Chaining Operator (?) and Nullish Coalescing Operator (??)

Optional Chaining Operator(?) (**)

//Car object
const car = {
  attributes: {
   year: 2021,
   model: "Ferrari"
  }
}

Before in javascript to validate that the attributes of an object exist, it was necessary to use the And operator (&&) to validate if the attributes of the object existed.

See the following example:

if (car && car.attributes && car.attributes.model) {
  console.log('Exist',  car.attributes.model)
} else {
  console.log('Do not exist')
}

# => "Exist Ferrari"

Now with Optional Chaining Operator (?) We can validate if the property exit will return undefined if the property attributes or model doesn’t exist.

if (car?.attributes?.model) {
  console.log('Exist',  car.attributes.model)
} else {
  console.log('Do not exist')
}

# => "Exist Ferrari"

Nullish Coalescing Operator(??) (**)

//Car object
const car = {
  attributes: {
   year: 2021,
   model: "Ferrari"
  }
}

If we want to get the car model then we would like below:


console.log(car.attributes.model);
# => "Ferrari"

Now the new car object does not have the model property, so we get an undefined value

//Car object
const car = {
  attributes: {
   year: 2021,
  }
}
console.log(car.attributes.model);
# => "undefined"

To avoid the undefined value the OR (| |) operator can be used, It will now return the value BMW because the property model is undefined. But what if the name property is empty like below example

console.log(car.attributes.model | | "BMW" );
# => "BMW"

Now the problem is when the property model exists but has an empty, undefined or null value we will get the BMW value and this is not right.

//Car object
const car = {
  attributes: {
   year: 2021,
   model: ""
  }
}
console.log(car.attributes.model | | "BMW" );
# => "BMW"

The solution for this problem is to use the Nullish Coalescing Operator (??), Which will print the result as an empty string.

console.log(car.attributes.model ?? "BMW" );
# => ""

Optional Chaining in JavaScript

The Optional Chaining Operator ? allows you to read the value of a property located deep within an object without having to validate each property in the object. It works in a similar way than the chaining operator ., except that instead of causing an error if a reference is nullish, the expression will return a value of undefined.

A common way to validate properties was to do something like this:

const player = {
  stats: {
    stamina: 40
  }
}

let stamina
if (player && player.stats) {
  stamina = player.stats.stamina
}

This was done because calling player.stats.stamina directly could led into an error being thrown if stats didn't exists, and sometimes even the execution would stop.

Using the Optional Chaining Operator, we could do something like this:

const player = {
  stats: {
    stamina: 40
  }
}

const stamina = player.stats?.stamina

The result is shorter and simpler, and in case stats didn't exists the value would be undefined, without an error being thrown.

Export defualt const is invalid because...

const is a lexical declaration

default expects a HoistableDeclaration, ClassDeclaration or AssignmentExpression

and thus, export default const someVariable is a SynthaxError

Practical difference undefined vs null in JS

body = await sendEmail({
      from: 'Demos.Guru <support@demos.guru>',
      replyTo: submission.reviewerEmail || undefined,
      to: user.email,

Today I learned one of the practical differences between null and undefined thanks to my good friend and Kickass Partner Richard Kaufman https://richardkaufman.xyz.

In the code snippet shown, setting replyTo to undefined makes it disappear from the object, whereas setting it to null would leave the property in the object, with its value set to null. Makes perfect sense.

Save a DOM node to a global variable in Chrome 71

img I've often wanted to be able to query/manipulate a DOM node. Super easy to do now that you can right-click in the inspector and assign to a global variable.

More info at https://developers.google.com/web/updates/2018/10/devtools#store

HTML5 Date Input doesn't work on Firefox #wtf

This one caught me by surprise today. Luckily, it's relatively simple to detect the missing functionality using Modernizr.js and use Datepickr instead.

$(function(){           
  if (!Modernizr.inputtypes.date) {
    $('input[type=date]').datepicker({
      dateFormat : 'yy-mm-dd'
    });
  }
});

http://stackoverflow.com/a/30503903/626048

Greenkeeper.io automated dependency management

This product just blew my mind, since I know how difficult it is to keep up with Node dependencies. You could manually track updates of your dependencies and test whether things continue to work. But it takes a lot of effort. So most of the time, your software is in a Schrödinger state of being potentially broken, and you have no idea until you run npm install and try the next time.

Greenkeeper handles the chores of dependency management. npm install and npm test is called immediately after an update. There is no doubt about the state of your software.

https://greenkeeper.io/

Use Axios for HTTP requests in Javascript

Axios is a slick promise-based HTTP client that works both in all modern browsers and server-side node.js. I like the simplicity of its interface.

axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

...and the fact that it supports concurrent requests without too much hassle

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // Both requests are now complete 
  }));