Categories
JavaScript Tips

Useful JavaScript Tips — Sets, Hidden Elements, and Loops

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some tips we should follow to write JavaScript code faster and better.

Sets

Sets are useful data structures for storing items without duplicates.

It’s an iterable object and it’s created with the Set constructor.

Initialize a Set

We can create a set with the Set constructor.

We write:

const set = new Set()

Add Items to a Set

We can add items to a set by using the add method.

So, we can write:

set.add('foo');
set.add('bar');

Check if an item is in a Set

Sets have a has method to check if an item is in the set.

For example, we can write:

set.has('foo');
set.has('bar');

Delete Item from a Set

We can call delete to remove a Set item.

For instance, we can write:

set.delete('foo');

Determine the Number of Items in a Set

The size property lets us get the number of items in a Set.

We can write:

set.size

Remove All Items from a Set

The clear method removes all items from a Set.

For example, we can write:

set.clear()

Iterate Items in a Set

We can use the for-of loop to loop through items in a Set.

For instance, we can write:

for (const k of set.keys()) {
  console.log(k)
}

to loop through the keys of the set.

Likewise, we can use the values() method to do the same thing:

for (const v of set.values()) {
  console.log(v)
}

There’s also the entries method to return an iterator:

const i = set.entries();

Then we can use the next method to get the next entry in the sequence:

i.next()

The returned object has the value or done properties.

done is false when there’s a next item in the sequence and true otherwise.

value has the value from the set.

Initialize Sets with Values

We can create sets with values using the Set constructor:

const set = new Set([1, 2, 3]);

Convert to an Array

We can convert to a Set to an array with the spread operator:

const arr = [...s.keys()]

or:

const arr = [...s.values()]

WeakSet

A WeakSet is a special kind of Set .

The items never get garbage collected in a Set.

Items in a WeakSet can be garbage collected.

Also, we can’t iterate over the items in a WeakSet.

We can’t clear all items from a WeakSet.

We also can’t check its size.

However, it has the add method to add items.

has method is available for checking if an item exists.

delete is used to delete an item.

Check if an Element is Hidden

We can check if an element is hidden using jQuery.

For instance, we can write:

$(element).is(":visible");

This checks for display: none .

Also, we can write:

$(element).is(":hidden");

and check for visibility: hidden .

We can get all the elements that are hidden with:

$(element).is(":hidden");

And we can get the ones with the visible selector with:

$('element:visible')

Deep Cloning an Object

We can deep clone an object with the JSON.stringify and JSON.parse method.

For instance, we can write:

const cloned = `JSON.parse(JSON.stringify(object));`

We can use it to clone the object with the function values inside the object.

Infinity will be converted to null and undefined values will be removed.

Also, regex literals are also removed.

Therefore, we can use this if we don’t have those values that’ll be converted or lost.

We can use the Lodash cloneDeep method to clone objects easily.

It clones everything in an object.

Object.assign and the spread syntax also copies the values of all enumerable own properties from one object to another.

We can write:

const cloned = Object.assign({}, obj);

or:

const cloned = {...obj };

For Each Loop

The best bet for loop through all items of an array easily for the for-of loop,

The Array instance also has the forEach method.

The old fashioned for loop can also do it.

We can write:

for (const a of arr){
  console.log(a);
}

or:

arr.forEach(a => {
  console.log(a);
})

or:

for (let i = 0; i < arr.length; i++){
  console.log(arr[i]);
}

Conclusion

Sets are a useful data structure for storing data without duplicates.

Also, we can check for hidden elements with jQuery.

There are many ways to iterate through an array.

Categories
JavaScript Tips

JavaScript Tips — Type Checks, Durations, and Promise Errors

Like any kind of apps, there are difficult issues to solve when we write JavaScript apps.

In this article, we’ll look at some solutions to common JavaScript problems.

Difference between typeof and instanceof

instanceof should be used for checking if an object is an instance of a constructor.

For instance, we can write:

foo instanceof Foo;

to check if foo is an instance of the Foo constructor.

typeof should be used for checking primitive types and functions.

For instance, we can write:

typeof 1 === 'number'

or:

typeof () => {} === 'function'

and they both return true .

However typeof null returns 'object' , so we can’t use typeof to check null .

Convert an HTMLCollection to an Array

To convert an HTMLCollection to an array, we can use the Array.from method or the spread operator to convert the HTMLCollection into an array.

For instance, we can write:

const arr = Array.from(htmlCollection);

or:

const arr = [...htmlCollection];

Both ways also work with NodeLists.

Remove an Item from a JavaScript Object

To remove an item from a JavaScript object, we can use the delete operator.

For instance, we can write:

const obj = { foo: 1, bar: 2 };
delete obj.foo;

Then the foo property is removed from obj .

Open a New Window or Tab

To open a new window or tab, we can use the window.open method.

For instance, we can write:

window.open('http://example.com', '_blank');

'_blank' makes window.open open a new window.

Newline in JavaScript Alert Box

To display a new line in a JavaScript alert box, we can add the new line character to the string we pass into alert .

For instance, we can write:

alert("line 1nline 2");

Then we display 2 lines of text since we have the n newline character.

Change the Text of a span Element in JavaScript

We can changer the text of a span element by changing the textContent property.

For instance, we can write:

document.getElementById("aSpan").textContent = "new stuff";

We just get the span and set the textContent property to a new string.

Check if a User is Using IE

To check if a user is using IE, then we can check the user agent.

For instance, we can write:

const ua = window.navigator.userAgent;
const ieIndex = ua.indexOf("MSIE");

if (ieIndex >= 0 || !!ua.match(/Trident.*rv:11./))  {
  console.log('is IE');
}
else {
  console.log('not IE');
}

We get the user agent with window.navigator.userAgent .

Then we get the index of the 'MSIE' string in the user agent and see if it’s there.

We also check if there’s the word 'Trident' in it as another check.

With both together, we can check if a browser is IE or not.

Get Hours Difference Between 2 Dates in Moment.js

To get the hours different between 2 dates in moment.js, we can use the duration and diff methods.

For instance, we can write:

const duration = moment.duration(end.diff(start));
const hours = duration.asHours();

We call the duration method to get the duration from subtract the end by the start , which are both moment objects.

Then we call asHours on duration to convert the duration to hours.

Access Variable Property by Name as String in JavaScript Object

We can use the bracket nation to access a JavaScript property with a variable.

For instance, we can write:

const foo = obj['foo'];

to get the foo property of obj .

Nested properties can be accessed with multiple brackets.

For instance, if we have:

const obj = { a: 1, b: { x: 2 }};

Then we can access x by writing:

const foo = obj['b']['x'];

JavaScript Promises — reject vs. throw

We can use throw in a promise callback.

Otherwise, we use reject .

For instance, we can write:

new Promise(() => {
  throw 'error';
})

We can use throw in the callback that we pass into the Promise constructor.

throw also terminates the control flow.

We can use reject in there or anywhere else:

new Promise((resolve, reject) => {
  reject('error');
})

We call reject , but the things after it can still run if they’re there.

They can both be caught with the catch method.

Conclusion

typeof and instanceof are used for checking different things.

We can get the duration between 2 dates with moment.js.

HTMLCollection and NodeLists can be converted to arrays.

We can check the user agent to check if a user is using IE.

Categories
JavaScript Tips

JavaScript Tips — Pausing or Stopping Programs , Accessing Script Elements

Like any kind of apps, there are difficult issues to solve when we write JavaScript apps.

In this article, we’ll look at some solutions to common JavaScript problems.

Pass Arguments to addEventListener Listener Function

There are a few ways to pass in arguments to an event listener function.

One way is to create another function and call that:

element.addEventListener("click", () => {
  foo(someVar);
}, false);

We just call foo inside the function with our arguments.

Also, we can set a property on an element and access it by writing:

const listener = (evt) => {
  window.alert(evt.currentTarget.foo);
}

element.addEventListener('click', listener, false);
element.foo = 'bar';

We get the element object with the currentTarget property.

Also, we can use bind to return a function with some arguments passed in:

function listener(foo, ev) {
  //...
}
element.addEventListener("click", listener.bind(null, foo), false);

We pass in foo as the 2nd argument of bind to pass it into the function.

Stop JavaScript Execution

There are a few ways to stop JavaScript programs.

One way is to throw an error.

For instance, we can write:

class `FatalError extends Error {}
throw new FatalError('fatal error');`

We can also use the return keyword in a function to stop it from running:

const foo = () => {
  `if(someEventHappened) {
     return;
  }
  //...
}`

Differences Between Deferred, Promise and Future in JavaScript

Deferred are objects that implement resolve , reject , and then .

We can create promises that call resolve , reject and returns an object that calls then .

Promise is a proxy object for storing the result of something that will be given in the future.

It also exposes a then method that accepts another target and returns a new promise.

A future is a deprecated term for either of those things.

Difference Between children and childNodes in JavaScript

children is a property of an element in JavaScript. It only returns child elements.

childNodes is a property of Node and can contain any node.

Combination of async, await and setTimeout

We can create a promise with setTimeout , then we can use async and await on it.

For instance, we can write:

const timeout = (ms) => {
  return new Promise(resolve => setTimeout(resolve, ms));
}

const foo = async () => {
  await timeout(3000);
  //...
}

We created a promise with the Promise constructor which calls resolve to fulfill the promise.

ms is the delay duration in milliseconds.

Then we can use it anywhere else with async and await .

In Node apps, we can also use the util package by writing:

const sleep = require('util').promisify(setTimeout)

Convert an Integer to Binary in JavaScript

We can convert an integer to binary with the zero-fill right shift operator.

For instance, we can write:

(dec >>> 0).toString(2);

We convert the decimal number dec to a binary with the >>> operator, which shifts the given number of bits to the right.

In this case, we shift 0 bits to the right to make it an unsigned integer.

Then we convert it to a string with toString with argument 2 to convert it to a binary string.

If we have a positive integer, then we can just call toString(2) on the number.

Reference the script Tag that Loaded the Currently-Executing Script

We can use document.currentScript to return the script element that’s currently being processed.

It’s simple and reliable.

We don’t need to modify the script tag.

It also works with async scripts that have the defer or async attribute.

And it works with scripts that are inserted dynamically.

It doesn’t work with IE and scripts with type module .

We can also select a script by ID:

<script id="someScript">
const currentScript = document.getElementById('someScript');
</script>

It has the same benefits as document.currentScript and it’s universally supported.

But we’ve to add an ID and may cause weird behavior in rare cases.

Also, we can add a custom data attribute.

For instance, we can write:

<script data-name="someScript">
const currentScript = document.querySelector('script[data-name="someScript"]');
</script>

We get the script by the data-name attribute.

It’s simple and works with scripts inserted dynamically.

But it’s less widely supported than the id attribute.

Finally, we can also get a script by the src value.

For instance, we can write:

const script = document.querySelector('script[src="//example.com/script.js"]');

This doesn’t work on local scripts.

But it works with defer and async and it’s reliable in those situations.

It also works with scripts inserted dynamically.

Conclusion

There are a few ways to get the script element on a page.

We can pass arguments to an event listener with bind or calling another function.

There are a few ways to pause or stop the execution of JavaScript programs.

Categories
JavaScript Tips

JavaScript Tips — Reset File Input, Format Date, and More

Like any kind of apps, there are difficult issues to solve when we write JavaScript apps.

In this article, we’ll look at some solutions to common JavaScript problems.

Reset a File Input

We can reset a file input by setting the value property of the input to an empty string.

For instance, we can write:

document.getElementById("file-input").value = "";

Comparing Date Part Only without Comparing Time in JavaScript

We can compare the dates without comparing the time if we set their hours to be the same.

To do that, we can set both to the same hours:

const date1 = new Date();  
const date2 = new Date(2011,8,20);  
date1.setHours(0, 0, 0, 0);  
date2.setHours(0, 0, 0, 0);

We set both date1 to date2 to midnight.

Now we can compare both only by their dates.

Trigger an onchange Event Manually

We can trigger change events by using the Event constructor.

For instance, we can write:

const event = new Event('change');  
element.dispatchEvent(event);

We create the event with the Event constructor.

Then we call dispatchEvent on the element with the event object as the argument.

Get String in YYYYMMDD Format from a JavaScript Date Object

To get a date as a string in YYYYMMDD format, we can use the built-in date methods to do it.

For instance, we can write:

const mm = date.getMonth() + 1;   
const dd = date.getDate();  
const yyyymmdd = [date.getFullYear(), `${mm > 9 ? '' : '0'}mm`,  
`${dd > 9 ? '' : '0'}dd`].join('');

We cal getFullYear to get the 4 digit year.

getMonth gets the month. We’ve to add 1 because the month is zero-based in a JavaScript date.

getDate returns the day.

Then we just put them all in the array and call join to combine them together.

Dot Notation vs. Brackets for JavaScript Property Access

We can use the dot or brackets notation for accessing JavaScript properties.

For instance, we can write:

const foo = form["foo"];

or:

const foo = form.foo;

They are the same for string keys.

Dot notation is faster and easier to read.

But square bracket notation lets us access properties with special characters or use variables to access properties.

Object Spread vs. Object.assign

We can use the spread syntax or Object.assign to copy or combine objects.

The spread syntax is shorter but is not dynamic.

For instance, we can write:

const obj = {...a, ...b};

We spread the entries of objects a and b into a new object and assigned it to obj .

It’s also available in ES2018 or later only.

If we need something more dynamic, we can use Object.assign .

It’s also available in older versions of JavaScript.

For instance, we can write:

const obj = Object.assign({}, a, b);

to do the same thing as before.

However, it’s longer than using the spread syntax.

We can also combine a dynamic number of objects if they’re in an array by using the spread operator:

const obj = Object.assign({}, ...objs);

where objs is an array of objects.

Differences between JSON and JSONP

The difference between JSON and JSONP is that we can use JSONP despite the same-origin policy.

The JSON is passed into a callback with JSONP.

But this is not the case with JSON.

For instance, a JSON response is:

{ "name": "james", "id": 5 }

But JSONP is passed into a callback which we specify with the callback query parameter.

For instance, if we have:

?callback=func

in the query string of the URL, then we write:

function func(json){  
  console.log(json.name);  
}

to get the JSONP response.

json is also:

{ "name": "james", "id": 5 }

Difference between Object.create() and new Constructor()

Object.create lets us create an object that inherits directly from another object.

If we use a constructor to create an object, then we create an object that inherits from the constructor’s prototype.

For instance, if we have:

const foo = Object.create(bar);

Then foo inherits properties from bar .

But if we write:

const foo = new Foo();

then foo inherits from Foo ‘s prototype.

Conclusion

We can reset a file input by setting its valuye property to an empty string.

Spread and Object.assign can do similar things.

Object.create and constructors are also different.

We can also call date methods to get parts of a date.

Categories
JavaScript Tips

JavaScript Tips — Parsing HTML, Reading Files, and More

Like any kind of apps, there are difficult issues to solve when we write JavaScript apps.

In this article, we’ll look at some solutions to common JavaScript problems.

Parse an HTML String with JavaScript

We can parse an HTML string with JavaScript by creating an html element that we don’t attach to the DOM.

Then we can use that to get what we want/

For instance, if we have:

const html = `
<html>

  <head>
    <title>title</title>
  </head>

  <body><a href='test'>link</a></body>

</html>
`

Then we can write:

const el = document.createElement('html');
el.innerHTML = html;
const anchor = el.querySelector('a');

We create the html element with createElement .

Then we set innerHTML with html to populate the items in the string in the new element.

Then we can use any DOM method like querySelector to get the element within the HTML.

There’s also the DOMParser constructor that’s used to parse the DOM.

For example, we can write:

const parser = new DOMParser();
const htmlDoc = parser.parseFromString(html, 'text/htm;');

Where html is the same string as we have before.

Convert String into Float

We can use the parseFloat function to parse a string into a floating-point number.

For instance, we can write:

const value = parseFloat("123.45");

We parse 123.45 into a floating-point number with it.

If we use decimal separators that aren’t periods, then we’ve to replace it with a period.

For instance, we can write:

const value = parseFloat("123,45".replace(",", "."));

Custom Attributes in HTML

If we want to add custom attributes to our elements, then we’ve to prefix it with the data- prefix.

For instance, we write:

<p data-date-changed="2020-01-01">Hello</p>

Then we can get the attribute value with getAttribute :

const dateChanged = document.querySelector("p").getAttribute("data-date-changed");

Get the YouTube video ID from a URL

We can get the YouTube video ID from the URL by splitting the query string.

To do that, we can use the URLSearchParams constructor.

For instance, we can write:

const urlSearchParams = new URLSearchParams(window.location.search.slice(1))
const videoId = urlSearchParams.get('v');

The first line creates the URLSearchParams instance with the query string.

We take out the ? from the window.location.search string by using lice .

Then we call get with the query parameter key v .

And videoId would be the video ID.

Import Modules from all Files in a Directory

We can import all modules from a directory if we export everything from each module.

So in one module, we can write:

things/index.js

export * from './moduleA';
export * from './moduleB';
export * from './moduleC';

Then we can import everything by writing:

import { ModuleA, ModuleB, ModuleC } from './things';

We export everything in each module in index.js .

Then we import them in another module.

We can do the same thing with default exports.

For example, we can write:

things/index.js

export { default as ModuleA } from './moduleA'
export { default as ModuleB } from './moduleB'
export { default as ModuleC } from './moduleC'

Then we can import them by writing:

import { ModuleA, ModuleB, ModuleC } from './things'

Difference Between innerText and innerHTML

The difference between innerText and innerHTML is that innerText only works with plain text.

Everything set as its value would be interpreted as plain text.

On the other hand, innerHTML would interpret HTML text as HTML and render them on the screen.

Resolve the C:fakepath When File is Selected from a File Input

We can’t get the full file path when we select the file input.

However, we can read the content of the file into a string.

For instance, we can write:

const input = document.querySelector("input");
input.onchange = () => {
  const fileReader = new FileReader();
  fileReader.readAsDataURL(input.files[0]);
  fileReader.onloadend = (event) => {
    console.log(event.target.result);
  }
}

The input element is input with type file .

We can watch for file changes by setting a listener to the onchange property.

Then we create a new FileReader instance and call the readAsDataURL method to read the data as a base64 string.

The onloadend listener attached to fileReader will run when the file is read.

event.target.result has the base64 string, which has the complete content of the file.

Conclusion

We can parse an HTML string by setting the string to innerHTML or use the DOMParser .

We can convert a string to a float with parseFloat .

To read a file’s content when it’s selected, we can use the FileReader constructor.

Also, we can export everything from a module with * .