Categories
JavaScript Best Practices

JavaScript Best Practices — Defining Functions and Calling Them

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at how the best way to define functions in our JavaScript code and call functions with a variable number of parameters.

Never Use the Function Constructor to Create a New function

In JavaScript, the Function constructor lets us define a function with strings for parameters and the function body.

All arguments but the last arguments are parameters, which are passed in as strings. The last argument is the function body, which is also passed in as strings.

The Function constructor returns a function that runs in the global scope only.

For instance, we can define a function as follows:

const add = new Function('a', 'b', 'return a + b');

In the code above, we called the Function constructor with the parameters a and b , which are defined as strings, and the function body return a + b .

This is bad because everything is defined as strings, which means that they’re hard to trace and debug. Also, there’s a chance that someone may pass in malicious strings into the Function constructor so that malicious code may run.

All returned functions also run in the global scope, which is probably not what we want.

Therefore, we shouldn’t run any code that uses the Function constructor.

Spacing in a Function Signature

Spacing in a function signature should be standardized and consistent. There should be no space after the function keyword or the function name. And there should be one closing parentheses and the opening curly brace.

For instance, we should write something like the following code:

function() {}
function add() {}

This way, we can read the name easily and the parentheses are easily readable as well.

Never Mutate Parameters

Mutating parameters is always bad. Since objects are passed by reference, they also mutate the arguments that are mutated outside.

For instance, if we write the following code:

const foo = (a) => a.foo = 2;
let a = {
  foo: 1
};
foo(a);
console.log(a);

Then in the code above, we have the a parameter in our foo function. Inside the function, we set a.foo to 2.

Then when we define the variable a with:

{
  foo: 1
}

Next when we call foo(a) , then we get that a is {foo: 2} because we mutate the parameter, which is propagated to the a variable itself because a is passed in by reference to the foo function.

What we should do instead is that we should assign the property’s value variable inside the function and then mutate that.

For instance, we can do the following:

const foo = (a) => {
  let bar = a.foo;
  bar = 2;
};

let a = {
  foo: 1
};
foo(a);
console.log(a);

This way, we get that a is:

{
  foo: 1
}

which is what we passed in originally. In the code above, we assigned a.foo to bar and set the value of bar to 2.

Prefer the Use of the Spread Operator ... to Call Functions with Variable Number of Parameters

With the introduction of the spread operator, we can use it to call functions with a variable number of parameters by calling it with an array that’s spread into arguments of the method by the spread operator.

This is much better than the old way, which is to call apply on the function to call a function with a variable number of parameters.

For instance, we can call the Math.max method to get the maximum number from an array of numbers as follows:

const max = Math.max(...[1, 2, 3]);

In the code above, we called Math.max with an array by using the spread operator. The spread operator spreads the array [1, 2, 3] into the arguments of the Math.max method,

Then we get 3 as the result of max .

This is much better than the old way, which is to use apply as follows:

const max = Math.max.apply(undefined, [1, 2, 3]);

In the code above, we called apply with 2 arguments, the first argument is the value of this , which can be anything since it’s a static function, but we chose undefined . The 2nd argument is the array of arguments that we want to pass into Math.max .

And then we get the same result. As we can see, it’s more a more complex way to get the same result.

Conclusion

We should never use the Function constructor to create a function. Also, we should use the spread operator to call functions that take a variable number of arguments rather than apply .

Categories
JavaScript Best Practices

JavaScript Best Practices — const and Destructuring

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at using const for declaring constants and using destructuring assignment syntax to assign property values and array entries to variables.

Using const to Declare Constants

The const keyword is one of the new JavaScript features that we should use often.

It lets us declare constants that can’t be reassigned to anything else its value has been set.

Also, we have to set it to a value when it’s defined so that it’s impossible for us to forget to assign it to something.

However, the object that it’s assigned to can still be mutated. For instance, we can still push on an array to add items to an array for example.

For instance, we can write the following code to declare a constant as follows:

const a = 1;

In the code above, we assigned a to 1. a is a constant, so we can’t assign it to any other value.

The is opposed to declaring variables with var or let , where we can assign the value to something else after it’s declared. For instance, we can write the following:

let a = 1;
a = 2;

or:

var b = 1;
b = 2;

If we reassign the value with something declared with const , we’ll get an error.

const can also be used with the destructuring assignment syntax, so we can declare multiple variables assign values to them all at once by using the syntax.

For instance, we can write the following:

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

In the code above, we assigned a to 1 and b to 2 because the object on the right side has properties a and b with values 1 and 2 respectively.

a and b will be constants so they can’t be assigned to something else. If we do try to do that, we’ll get an error.

We can also do that with arrays as follows:

const [a, b] = [1, 2];

and get the same result as in the previous example.

Destructuring Arrays and Objects

The destructuring syntax in JavaScript is another syntax that we should use often.

It helps us destructure arrays and objects into variables. As we can see, from the examples in the previous section, we can destructure array entries and object properties into variables.

It’s easy to use and works with any nesting levels. We can destructure a nested array as follows:

const [
  [a], b
] = [
  [1], 2
];

In the code above, we destructured a nested array by putting the a inside the array on the left side. Then on the right side, we have 1 inside the array. Therefore, 1 will be assigned to a by the position that it’s located in the nested array.

Likewise, we can do the same thing with nested objects as follows:

const {
  a,
  b: {
    c
  }
} = {
  a: 1,
  b: {
    c: 2
  }
};

In the code above, we have the nested property c in the b property. By checking the position of c , the destructuring will be done because c on both sides have the same nesting level.

Therefore, it’s value will be assigned to c .

There’re more ways we can use the destructuring syntax. For instance, it’s very useful for destructuring properties and array entries in object parameters of functions.

We can destructure array entries in parameters into variables as follows:

const foo = ([a, b]) => a + b

In the code, we set the first 2 entries of the array parameter as values of variables a and b .

Then when we call it as follows:

foo([1, 2]);

Then we get 3 because a is 1 and b is 2.

Likewise, we can do that with object parameters. For instance, we can write the following:

const foo = ({
  a,
  b
}) => a + b

and we can call it as follows:

foo({
  a: 1,
  b: 2
})

and get the same return value of 3 because of the destructuring syntax applied to the object.

We can also use it in the for...of loop as follows:

for (const [key, value] of new Map([
    ['a', 1],
    ['b', 2]
  ])) {
  console.log(`${key} - ${value}`);
}

In the code above, we looped through a Map instance with the for...of loop and destructured the entries using the destructuring syntax into the key and value constants.

Therefore, we will see the items’ key and value logged.

Since the destructuring syntax is so convenient, we should use it everywhere.

Conclusion

We should use const to declare constants so that they can’t be reassigned to a different value accidentally.

The destructuring syntax is a very convenient way to assign array entries and object property values to variables directly. Therefore, we should use it everywhere.

Categories
jQuery Tips

jQuery Tips — Form Values, Select, and Request Headers

Despite its age, jQuery is still a popular library for manipulating the DOM.

In this article, we’ll look at some tips for working with jQuery.

Get Form Input Field Values Using jQuery

We can get the form fields and their values with various methods.

One way is to call submit and then get all the input fields.

For example, we can write:

$('form').submit(() => {
  const inputs = $('form :input');
  const values = {};
  inputs.each(function() {
    values[this.name] = $(this).val();
  });
});

We get the form element and call the submit method on it,

Then we loop through the inputs and call each to loop through their values.

In the each callback, we get the form name of the field with this.name and the inputted value with $(this).val() .

jQuery also has the serializeArray method to let us get the fields as an array.

Then we can use each on it to loop through each field.

For example, we can write:

const values = {};
$.each($('form').serializeArray(), (i, field) => {
  values[field.name] = field.value;
});

We call serializeArray on the form element to convert the fields into an array.

Then we have a callback that gets the field with the field parameter.

We get the name and value properties to get the name and value attributes respectively.

Also, we can call serialize to get the value of each field.

For example, we can write:

$('form').submit(function() {
  const values = $(this).serialize();
});

We get the values from the form element with the serialize method.

Get the Rendered Height of an Element with jQuery

We can get the rendered height of an element with jQuery by using various methods.

To do this, we can write any of the following:

$('#foo').height();
$('#foo').innerHeight();
$('#foo').outerHeight();
$('#foo').outerHeight(true);

height returns the height of the element excluding the margin, padding, or border.

innerHeight gets the height of the div with padding but without the border or margin.

outerHeight returns the height of the element including padding and border.

outerHeight with the argument true returns the height including border, margin, and padding.

Get All Options of a Select Using jQuery

To get all options of a select element using jQuery, we can just use the $ method with the selector to get all our options.

For instance, we can write:

$("select#id option").each(function() {
  //...
});

We get the select element with the ID id ‘s option elements with this selector.

Then we use each to iterate through all of them.

Alternatively, we can use the map method to get the values from the option elements:

$("select#id option").map(function() {
  return $(this).val();
}).get();

We get the value attribute value of each option element with the callback that we have.

get returns the DOM element matched bu the jQuery object.

We can also use find to specifically get the option child elements in the select element.

For example, we can write:

$('select#id').find('option').each(function() {
   console.log($(this).val());
});

We call find to get the option elements that are the child of the select with the ID id .

And we get the value of the option inside the callback.

Convert a jQuery Object into a String

We can convert a jQuery object into a string bu calling the html method.

For example, we can write:

$('<div>').append($('#foo').clone()).html();

to create a div.

Then we append the clone of the element with ID foo into it.

Finally, we get the HTML string representation of the element with ID foo .

Also, we can use the outerHTML property to make our lives easier.

For instance, we can write:

$('#foo').prop('outerHTML');

We get the element with ID foo and call the prop method on it with 'outerHTML' to get the outerHTML property of the element.

Add Request Headers to Request with jQuery

We can add access control request headers to a request with the setRequestHeader method.

For instance, we can write:

$.ajax({
  type: "POST",
  beforeSend(request) {
    request.setRequestHeader("Authority", authorizationToken);
  },
  url: "/login",
  data: JSON.stringify(request),
  processData: false,
  success(msg) {
    alert('success');
  }
});

We call ajax with the beforeSend method to run code before a request, which includes adding request headers.

It takes a request parameter, which we can call setRequestHeader with.

The first argument is the key and the 2nd is the value.

Conclusion

There are many ways to get the height of an element.

We can add request headers to a request with ajax .

We can also get form values and options in various ways.

Categories
jQuery Tips

jQuery Tips — Arrays, Ajax, Textbox Changes, and Arrow Keys

Despite its age, jQuery is still a popular library for manipulating the DOM.

In this article, we’ll look at some tips for working with jQuery.

Remove Specific Value from an Array Using jQuery

jQuery has a grep method to let us return a new array that doesn’t include the item that we want to remove.

For instance, we can write:

const arr = [1, 2, 2, 6, 2, 6, 8, 3];
const itemToRemove = 2;
const newArr = $.grep(arr, (value) => {
  return value !== itemToRemove;
});

We call $.grep with an array to check for.

And we pass in a callback to return an array that returns a boolean expression to return the matches.

value !== itemToRemove indicates that we return an array without the itemToRemove ‘s value.

Use Basic Authentication with jQuery and Ajax

With jQuery, we can use basic authentication if we set the request header.

To do that, we can write:

beforeSend(xhr) {
  const token = btoa(`${username}:${password}`);
  xhr.setRequestHeader ("Authorization", `Basic ${token}`);
},

We create a token from the username and password combined together.

Then we set the Authorization header with the token.

Binding Arrow Keys with jQuery

We can listen for arrow key presses by using the keydown method.

For instance, we can write:

const arrow = { left: 37, up: 38, right: 39, down: 40 };

$(window).keydown((e) => {
  switch (e.which) {
    case arrow.left:
      //..
      break;
    case arrow.up:
      //..
      break;
    case arrow.right:
      //..
      break;
    case arrow.down:
      //..
      break;
  }
});

We listen to the key down on the window.

Then we can get the event object in the parameter of the callback.

It has the which property with the key code for the key that we pressed.

Then we can use a switch statement to look for matches for the key that’s pressed.

Converting a JavaScript Object to an Array Using jQuery

We can convert a JavaScript object to an array using the map method.

It works with both objects and arrays.

For instance, we can write:

const obj = {
  1: 'foo',
  2: 'bar'
};
const array = $.map(obj, (value, index) => {
  return [value];
});
console.log(array);

We call map with our obj object as the first argument.

In the 2nd argument, we pass in a callback that takes value of each object entry as the first parameter.

The index is the key that’s being looped through is the 2nd parameter.

We return the value in the array to return put the item in the array.

It should be enclosed in an array.

Then we can check the array value with the console log.

How to Detect that a Textbox’s Content has Changed

To detect that a text box’s content has changed, we can listen to the input event.

For example, we can write:

$('#textarea').on('input', () => {
  //...
});

We can do the same thing with bind :

$('#textarea').bind('input', () => {
  //...
});

We can also listen to the propertychange and paste events to listen to input change and pasting text.

For instance, we can write:

$('#textarea').on('input propertychange paste', () => {
  //...
});

Scroll Automatically to the Bottom of the Page

We can scroll automatically to the bottom of the page by calling animate to scroll to the bottom of the page.

For instance, we can write:

$('html,body').animate({ scrollTop: document.body.scrollHeight }, "fast");

We call animate with an object.

The object has some options for scrolling.

scrollTop is the y-coordinate that we want to scroll to.

The 2nd argument is the speed of the animation.

Show Loading Spinner in jQuery

We can show and hide a loading spinner with the show and hide method.

For instance, we can write:

const spinner = $('#spinner').hide();
$(document)
  .ajaxStart(() => {
    spinner.show();
  })
  .ajaxStop(() => {
    spinner.hide();
  });

spinner has the loading spinner element.

We hide it at the beginning.

Then when the Ajax request starts, we show the spinner.

This is done by passing in a callback to the ajaxStart method and then calling show on our spinner element.

Likewise, we can hide the spinner by call spinner.hide() in the callback of the ajaxStop method.

Conclusion

jQuery has a grep method that acts like the filter method of JavaScript arrays.

We can listen to arrow key presses with jQuery.

ajaxStart and ajaxStop let us run code when the Ajax request starts and end respectively.

jQuery’s map method works with objects and arrays.

Categories
jQuery Tips

jQuery Tips — Disable Scroll, Copy for Formatting, Toggle Elements

Despite its age, jQuery is still a popular library for manipulating the DOM.

In this article, we’ll look at some tips for working with jQuery.

Disable Scrolling Temporarily

We can disable scrolling temporarily by hiding the overflow from the div that we’re scrolling.

For instance, we can create a disableScroll function to disable the scrolling.

We can do that by writing:

function disableScroll() {
  document.getElementById('scrollbar').style.display = 'block';
  document.body.style.overflow = 'hidden';
}

We get the element with ID scrollbar and make it display as a block element.

Then set overflow to hidden.

Copy to Clipboard with Formatting Using jQuery

To copy text to the clipboard with formatting using jQuery, we can make our element that has formatting editable.

Then we can set a handler for the focus event.

When the element is focused, we call the document.execCommand method to select all the items.

Once the items are selected, we can call the copy command on the document.

And then we call removeChild on the element.

To do that, we can write:

const copyWithFormatting = (elementId) => {
  const temp = document.createElement("div");
  temp.setAttribute("contentEditable", true);
  temp.innerHTML = document.getElementById(elementId).innerHTML;
  temp.setAttribute("onfocus", "document.execCommand('selectAll', false, null)");
  document.body.appendChild(temp);
  temp.focus();
  document.execCommand("copy");
  document.body.removeChild(temp);
}

We create a temporary div, then make that editable by setting the contentEditable attribute.

Then we get the HTML from the element with elementId and set that as the HTML content of the innerHTML of the temp element.

And then we add a focus handler on it to select all the items in the element with:

temp.setAttribute("onfocus", "document.execCommand('selectAll', false, null)");

Then we call appendChild to attach that to the body.

And then we focus on the temporary element we created.

Once we did that, we can call the 'copy' command to copy the content of the temporary element since we selected everything.

And then when we finish copying, we call removeChild to remove the temporary element.

However, we’ve to know that execCommand is marked as obsolete.

When the new clipboard API is widely available, then we should replace it with the new API.

Skip to the Next Iteration in jQuery.each()

To skip to the next iteration with $.each , we can return true in the callback to skip to the next iteration.

For instance, we can write:

const arr = ['foo', 'bar', 'baz', 'qux'];
$.each(arr, (i) => {
  if (arr[i] === 'bar') {
    return true;
  }
  console.log(arr[i]);
});

We skip to the next iteration by returning true in our callback as we did in:

if (arr[i] === 'bar') {
  return true;
}

Change CSS Display None or Block Property Using jQuery

jQuery has dedicated methods to let us change elements to display block or none.

For instance, we can write:

$('#foo').hide();

to hide the element with ID foo.

Also, we can write:

$('#foo').show();

to show our the element with the ID foo.

There’s also the CSS method that we can use to do the same thing.

For instance, we can write:

$("#foo").css("display", "none");

to hide the element and free up space for other elements.

And we can write:

$("#foo").css("display", "block");

to make the element with ID foo display as a block element.

Submitting a Form on ‘Enter’ with jQuery

We can submit a form when the Enter key is pressed by listening to the keypress event with the keypress method.

For instance, we can write:

$('.input').keypress((e) => {
  if (e.which === 13) {
    $('form#task').submit();
    return false;
  }
});

We listen to the keypress event on the element with class input .

We call keypress to add the keypress listener to it.

In the handler callback, we use the which property to get the key code for the key that’s pressed.

If it’s 13, then the Enter key is pressed.

Then we call submit on the form element with ID task to submit the form’s content.

And we’ve to return false at the end to stop the default submit behavior and to stop the propagation of the keypress event.

Conclusion

We can disable scrolling by disabling overflow from the body.

To copy content from an element, we can use the document.execCommand method to do it.

Even though it’s obsolete, we can use it until the clipboard API is widely available.

And we can return true to skip an iteration when we use each .