Categories
JavaScript JavaScript Basics

Using JavaScript’s Object Constructor — Part 2

In JavaScript, the object constructor lets us create object wrapper with the given values. It will create an empty object if null or undefined is passed into the object constructor. If the value passed into the constructor is an object already, then it will return the object.

The object constructor has two properties. It has a length property that is always 1, and like all other objects, the object constructor has a prototype to get all the property additions to the type object.

Continuing from Part 1, the object constructor has many useful methods that can be used without constructing a new object.


Object.fromEntries()

The Object.fromEntries() method accepts an array with arrays of key-value pairs with the key as the first element and the value of the corresponding key as the second element. We can also pass in other iterables with the same kind of arrays into the method.

For example, we can write the following code to pass in an array of key-value pairs to create an object:

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

const obj = Object.fromEntries(entries);
console.log(obj);

The resulting object obj should be {a: 1, b: 2} as we can see from the console.log output when the code above is run. We can pass in other iterables, such as maps:

const entries = new Map([  
  ['a', 1],  
  ['b', 2]  
]);

const obj = Object.fromEntries(entries);
console.log(obj);

We should see the same thing logged. Also, we can convert arrays to objects with the following code:

const arr = [1,2,3];  
const entries = arr.map((value, index) => [index, value]);
const obj = Object.fromEntries(entries);
console.log(obj);

When the code above is run, we get {0: 1, 1: 2, 2: 3} since we mapped the index of each array entry to the key and the value of each array entry to the value.


Object.getOwnPropertyDescriptor()

The Object.getOwnPropertyDescriptor() method gets the property descriptor of a property in the object and returns it. As the name suggests, it only gets the property descriptor of the object that’s in the object itself and not up the prototype chain.

A property descriptor is an object with the property names as keys and the properties writable, configurable, enumerable, and value as properties of the property name keys.

writable means that the property’s value can be changed. configurable means the property descriptor may be changed and if the property can be deleted from the object.

The enumerable property means that the property shows up during enumeration of the properties with the for...in loop and value is the value of the property.

For example, if we log a property descriptor of an object with:

const obj = {  
  a: 1  
}const descriptor = Object.getOwnPropertyDescriptor(obj, 'a');  
console.log(descriptor);

We get {value: 1, writable: true, enumerable: true, configurable: true} . The value is the value of the property and the rest of the properties are the property descriptor’s properties. If we have property getters and setters, they are also returned with the method call:

let obj = {};  
let value;  
Object.defineProperty(obj, 'a', {  
  get() {  
    return value;  
  },  
  set(a) {  
    value = a;  
  }  
});  
  
const descriptor = Object.getOwnPropertyDescriptor(obj, 'a');  
console.log(descriptor);

When the code above is run, we get the get and set functions back in the descriptor object.


Object.getOwnPropertyDescriptors()

While the Object.getOwnPropertyDescriptor() gets the property descriptor for a single object, the Object.getOwnPropertyDescriptors() gets all the property descriptors of an object in one object—once again without the properties that are inherited by this object up the prototype chain, with the property names as the keys and the property descriptor of the corresponding property name key as the value.

For example, if we have

const obj = {  
  a: 1,  
  b: 2  
}  
const descriptors = Object.getOwnPropertyDescriptors(obj);  
console.log(descriptors);

then we get

{  
  "a": {  
    "value": 1,  
    "writable": true,  
    "enumerable": true,  
    "configurable": true  
  },  
  "b": {  
    "value": 2,  
    "writable": true,  
    "enumerable": true,  
    "configurable": true  
  }  
}

We get all the values and the property descriptor attributes of each property. Like with Object.getOwnPropertyDescriptor(), this method has the same definitions for the property descriptors.

A property descriptor is an object with the property names as keys and the properties writable, configurable, enumerable, and value as properties of the property name keys.

The writable means that the property’s value can be changed. configurable means the property descriptor may be changed and if the property can be deleted from the object.

The enumerable property means that the property shows up during enumeration of the properties with the for...in loop, and value is the value of the property.


Object.getOwnPropertyNames()

The Object.getOwnPropertyNames() method returns an array of property names that are defined in the object itself and not in any object up the prototype chain. Non-enumerable properties are also returned except for those that are symbols. For example, if we have:

let obj = {  
  a: 1,  
  b: 2  
}

Object.defineProperty(obj, 'c', {  
  "value": 2,  
  "writable": true,  
  "enumerable": false,  
  "configurable": true  
})

const names = Object.getOwnPropertyNames(obj);  
console.log(names);

If we run the code above, we get [“a”, “b”, “c”] returned since all properties defined except ones identified with Symbols are returned. If we have Symbols in our object, we won’t see it in the returned array. For example, if we have

let obj = {  
  a: 1,  
  b: 2,  
  [Symbol('foo')]: 3  
}  
Object.defineProperty(obj, 'c', {  
  "value": 4,  
  "writable": true,  
  "enumerable": false,  
  "configurable": true  
})  
const names = Object.getOwnPropertyNames(obj);  
console.log(names);

we still see [“a”, “b”, “c”] if we run the code above since symbols aren’t included in the array. We have the Object.getOwnPropertySymbols() to get properties that are identified with symbols.


Object.getOwnPropertySymbols()

The Object.getOwnPropertySymbols() returns an array of symbols that are used as identifiers in the properties of an object.

It only gets the property identifiers that are named with symbols and nothing else.

Also, it doesn’t traverse up to the prototype chain to get properties of objects up the prototype chain. For example, if we have the following code:

let obj = {  
  a: 1,  
  b: 2,  
  [Symbol('foo')]: 3  
}  
Object.defineProperty(obj, 'c', {  
  "value": 4,  
  "writable": true,  
  "enumerable": false,  
  "configurable": true  
})  
const symbols = Object.getOwnPropertySymbols(obj);  
console.log(symbols);

we get [Symbol(foo)] logged as we expected.


Object.getPrototypeOf()

The Object.getPrototypeOf() method gets the prototype of an object, which is the same as the [[Prototype]] property of the specified object. For example, if we have

const prototype1 = {};  
const obj = Object.create(prototype1);  
console.log(Object.getPrototypeOf(obj) === prototype1);

the console.log will output true since the first argument of Object.create is the prototype object for the object that it returns; likewise, if we use Object.setPrototypeOf() method to set the prototype of an existing object.

const prototype2 = {};  
let obj2 = {};  
Object.setPrototypeOf(obj2, prototype2);  
console.log(Object.getPrototypeOf(obj2) === prototype2);

The console.log will also output true since set the prototype of obj2 explicitly.


Object.is()

The Object.is() method compares whether two objects passed in its argument are the same value. Two values are the same if they’re:

  • both undefined
  • both null
  • both true or both false
  • both strings with the same length and same characters in the same order
  • both objects having the same references
  • both numbers and both +0 , or both -0 or both NaN or both non-zero and both not NaN and they both have the same value

It doesn’t convert types like the == operator to compare objects and don’t convert truthy or falsy values to booleans. Also, it’s not the same as comparing objects with the === operator because with the === operator, -0 and +0 are equal and NaN is not the same as itself.

For example, we can make the following comparisons:

Object.is('a', 'a');             // true  
Object.is(document, document);   // true  
  
Object.is('a', 'b');             // false  
Object.is([], []);               // false  
  
const obj = { a: 1 };  
const obj2 = { a: 1 };  
Object.is(obj, obj);             // true  
Object.is(obj, obj2);            // false  
  
Object.is(null, null);           // true  
  
Object.is(0, -0);                // false  
Object.is(-0, -0);               // true  
Object.is(NaN, 0/0);             // true

As we can see, only object references and values are compared. The object’s content isn’t compared, so even if two objects have the same content, they’re still considered different since their references in memory are different, as they’re defined by two different variables.


Object.isExtensible()

The Object.isExtensible() method checks whether an object’s property is extensible. That is if an object can have new properties added to it. For example, if we have:

const obj = {};  
const obj2 = {};console.log(Object.isExtensible(obj));Object.preventExtensions(obj2);console.log(Object.isExtensible(obj2));

Then console.log(Object.isExtensible(obj)); will log true since we didn’t explicitly prevent adding new properties to obj . However, console.log(Object.isExtensible(obj2)); will log false since we called Object.preventExtensions(obj2); to prevent new properties from being added to obj2 .

If we run the following code, we also get false logged in both console.log statements because we explicitly prevented the objects obj and obj2 from having new properties added with the Object.freeze() and Object.seal() methods respectively:

const obj = {};  
const obj2 = {};  
Object.freeze(obj);  
console.log(Object.isExtensible(obj));Object.seal(obj2);  
console.log(Object.isExtensible(obj2));

Object.isFrozen()

The Object.isFrozen() method determines if an object is frozen. Frozen means that all properties’ values in an object can’t be changed. Also, new properties can’t be added to it, and existing property descriptors for the frozen object can’t be changed. The object is frozen in place. This method doesn’t return a new frozen object. Instead, it returns the original object before it’s frozen. The frozen object’s prototype also can’t be changed. For example, if we have:

const obj = {  
  a: 1  
};console.log(Object.isFrozen(obj));

We get false from the console.log statement because we didn’t explicitly freeze the object by calling Object.freeze(obj). On the other hand, we have frozen the object, then Object.isFrozen() will return true. For example:

const obj = {  
  a: 1  
};Object.freeze(obj);  
console.log(Object.isFrozen(obj));

Then we get true from the console.log statement because we froze the object by calling Object.freeze(obj). If primitive values are passed in, Object.isFrozen() will return true since they’re immutable. For example, if we have:

console.log(Object.isFrozen(1));  
console.log(Object.isFrozen('string'));  
console.log(Object.isFrozen(null));  
console.log(Object.isFrozen(undefined));  
console.log(Object.isFrozen(NaN));  
console.log(Object.isFrozen(true));  
console.log(Object.isFrozen(Symbol('a')));

Then all the console.log statement will be true since they’re all immutable.

The Object constructor has many more methods for constructing objects from an array of an array with key and value of properties and also methods to get property descriptors from objects, property names, property symbols, gets the keys of an object and prevent properties from being added or deleted or modify their property descriptors.

Categories
JavaScript

JavaScript Events Handlers — Input Events

In JavaScript, events are actions that happen in an app. They’re triggered by various things like inputs being entered, forms being submitted, and changes in an element like resizing, or errors that happen when an app is running, etc. We can assign an event handler to respond to and handle these events. Events that happen to DOM elements can be handled by assigning an event handler to properties of the DOM object for the corresponding events. In this article, we’ll look at how to use the oninput and oninvalid properties of an editable input element.

oninput

The oninput property of a DOM element lets us assign an event handler to handle the input event which is fired when the value of an input, select, or textarea element has been changed. It is also fired when any content in an element with the contenteditable attribute enabled, and also to any element when designMode is turned on. In the case of contentEditable and designMode, the event target is the editing host. If these properties are applied to multiple elements, then the editing host is the nearest ancestor element whose parent isn’t editable.

For input elements with the type attribute set to checkbox or radio, the input event will fire whenever a user toggles the control. However, this isn’t always the case for every browser.

The input event is fired whenever the value changes, unlike the change event where the event is only fired when the input value is committed, such as when the user presses the Enter key or select a value from a list of options, etc.

For example, we can assign an event handler function to log the input value of an input event as we do in the following HTML code:

<input placeholder="Enter some text" name="name"/>  
<p id="value-log"></p>

Then in the JavaScript code, we can write:

const input = document.querySelector('input');  
const log = document.getElementById('value-log');
const updateValue = (e) => {  
  log.textContent = e.target.value;  
}
input.oninput = updateValue;

Then we should see an input text box with a p element that displays the value that was inputted as it’s changed.

Similarly, we can use it for a select element. First, we write the following HTML code:

<select name="name">  
  <option value='Apple'>Apple</option>  
  <option value='Orange'>Orange</option>  
  <option value='Grape'>Grape</option>  
</select>  
<p id="value-log"></p>

Then the JavaScript is very similar to what we have before:

const select = document.querySelector('select');  
const log = document.getElementById('value-log');
const updateValue = (e) => {  
  log.textContent = e.target.value;  
}
select.oninput = updateValue;

Note that the value is displayed only when we make a selection, so it won’t show any value when we first load the page since we have nothing selected.

For checkboxes, the code is going to be quite different from text input. We have to check for if the checkbox is checked and then get the value if it is if we want to log the checked values.

For instance, if we have the following HTML code for some checkboxes:

<input type='checkbox' value='Apple' name="name" id='0' /> Apple  
<input type='checkbox' value='Grape' name="name" id='1' /> Grape  
<input type='checkbox' value='Banana' name="name" id='2' /> Banana  
<p id="value-log"></p>

Then we have to attach an oninput event handler function for each checkbox like we do in the following code:

const checkboxes = document.querySelectorAll('input');  
const log = document.getElementById('value-log');

let choices = [];

const updateValue = (e) => {    
  choices[e.target.id] = e.target.checked ? e.target.value : undefined;  
  log.textContent = choices.join(' ');  
}

checkboxes.forEach((c, i) => {  
  c.oninput = updateValue;  
})

In the code above, we looped through all the checkbox elements and set the updateValue event handler function to the oninput property of each checkbox element, and then in the updateValue function, we set the entry in the choices array by checking for the checked value for the checkbox with the given ID, and then we set the value in the choices array only if it’s checked by checking the e.target.checked property.

For radio buttons, it’s easier than dealing with checkboxes since there’s only one possible choice for a group of radio buttons. The HTML code is similar to the checkboxes like we have in the following code:

<input type='radio' value='Apple' name="name" id='0' /> Apple  
<input type='radio' value='Grape' name="name" id='1' /> Grape  
<input type='radio' value='Banana' name="name" id='2' /> Banana  
<p id="value-log"></p>

Then in the JavaScript code, we attach an event handler function to each radio button element like we do in the code below:

const radioButtons = document.querySelectorAll('input');  
const log = document.getElementById('value-log');
const updateValue = (e) => {    
  log.textContent = e.target.value;  
}

radioButtons.forEach((c, i) => {  
  c.oninput = updateValue;  
})

In the code above, we set the value straight in the value-log element since we only want the currently selected choice.

oninvalid

We can assign an event handler to handle the invalid event by setting the oninvalid property of a DOM element. The invalid property is fired when the submittable element has been checked and input validation fails. For example, it’ll fire when an input element has an input that doesn’t meet the requirements defined in the HTML code. The validation is done by checking the required and pattern attributes of the input or textarea elements.

For example, we can use it for validating the inputs of a form element:

<form id="form">  
  <label for="city">First Name</label>  
  <input type="text" id="first-name" required>  
  <p id="first-name-error" hidden>Please fill out first name.</p>  
  <br> 
  <label for="city">Last Name</label>  
  <input type="text" id="last-name" required>  
  <p id="last-name-error" hidden>Please fill out last name.</p>  
  <br> 
  <label for="city">Email</label>  
  <input type="text" id="email" required pattern='[^@\]+@\[^\.]+\..+'>  
  <p id="email-error" hidden>Please fill out email.</p>  
  <br> 
  <button type="submit">Submit</button>  
</form>

Then in the corresponding JavaScript code, we can set the oninvalid property of each input element to handle the invalid event of each input element as we do in the following code:

const form = document.querySelector('form');  
const inputs = document.querySelectorAll('input');

inputs.forEach(input => {  
 input.oninvalid = (e) => {      
    document.getElementById(`${e.target.id}-error`).removeAttribute('hidden');  
  }  
})

form.onsubmit = (e) => {  
  console.log(e);  
  e.preventDefault();  
}

Also, we have to call preventDefault() on the onsubmit event handler because we don’t want to submit the form values anywhere in this example. To attach the invalid event handler to all the input elements, we get all the input elements with the document.querySelectorAll method, then we loop each DOM element object and then set the oninvalid property to our event handler function. Inside the event handler function, we just toggle the hidden attribute off whenever an invalid event is fired for the input element.

The oninput property of a DOM element lets us assign an event handler to handle the input event which is fired when the value of an input , select or textarea element has been changed. It also fired when any content in an element with the contenteditable attribute enabled, and also to any element when designMode is turned on. We can use it to handle the situation where a value is entered or selected. The event handler function is run whenever input is changed before it’s committed.

We can assign an event handler to handle the invalid event by setting the oninvalid property of a DOM element. The invalid property is fired when the submittable element has been checked and input validation fails. For example, it’ll fire when an input element has an input that doesn’t meet the requirements defined in the HTML code. The validation is done by checking the required and pattern attributes of the input or textarea elements.

Categories
Express JavaScript

Guide to the Express Application Object — Routing

The core part of an Express app is the Application object. It’s the application itself.

In this piece, we’ll look at the methods of the app object and what we can do with it.


app.METHOD(path, callback [, callback …])

This method routes an HTTP request. METHOD is a placeholder for various routing methods that Express supports.

It takes the following arguments:

  • path — It can be a string or regex representing paths or patterns of paths. The default is /.
  • callback — a function to handle requests. It can be a middleware function, a series of them, array of them, or a combination of all of the above.

The following routing methods are supported by Express:

  • checkout
  • copy
  • delete
  • get
  • head
  • lock
  • merge
  • mkactivity
  • mkcol
  • move
  • m-search
  • notify
  • options
  • patch
  • post
  • purge
  • put
  • report
  • search
  • subscribe
  • trace
  • unlock
  • unsubscribe

All methods take the same arguments and work exactly the same way. So app.get and app.unlock are the same.


app.param([name], callback)

app.param adds callback triggers for route parameters. name is the parameter or an array of them. callback is a callback function.

The parameters of the callback are the request object, response object, next middleware function, the value of the parameter, and the name of the parameter in the given order.

For example, we can use it as follows:

The code above will get the id URL parameter when it exists with the app.param callback.

Then in the callback, we get id to req.id and call next to call our route handler in app.get.

Then we call res.send(req.id); to send the response with req.id, which we set earlier.

Note that id in app.param has to match :id with the route handlers.

We can pass in an array of parameters that we want to watch for:

Then if we make a request for /1/foo, we’ll get 1 and foo one at a time as the value of the value parameter.


app.path()

app.path returns the path of mounted apps as a string.

For example, we can use it as follows:

Then we get '' for app.path(), '/foo' for foo.path(), and '/foo/bar' for bar.path() since we mounted foo to app and bar to foo.

<img class="s t u hh ai" src="https://miro.medium.com/max/6438/0*hC4qa3eKTWD_g_hs" width="3219" height="4836" srcSet="https://miro.medium.com/max/552/0*hC4qa3eKTWD_g_hs 276w, https://miro.medium.com/max/1104/0*hC4qa3eKTWD_g_hs 552w, https://miro.medium.com/max/1280/0*hC4qa3eKTWD_g_hs 640w, https://miro.medium.com/max/1400/0*hC4qa3eKTWD_g_hs 700w" sizes="700px" role="presentation"/>

Photo by Bundo Kim on Unsplash.


app.post(path, callback [, callback …])

We can use the app.post method to handle POST requests with the given path by passing in a callback route handler.

It takes the following arguments:

  • path — It can be a string or regex representing paths or patterns of paths. The default is /.
  • callback — a function to handle requests. It can be a middleware function, a series of them, array of them, or a combination of all of the above.

For example, we can use it as follows:

Then when we make a POST request with a client like Postman, we should see “POST request made.”


app.put(path, callback [, callback …])

We can use the app.put method to handle PUT requests with the given path by passing in a callback route handler.

It takes the following arguments:

  • path — It can be a string or regex representing paths or patterns of paths. The default is /.
  • callback — a function to handle requests. It can be a middleware function, a series of them, array of them, or a combination of all of the above.

For example, we can use it as follows:

Then when we make a PUT request with a client like Postman, we should see “PUT request made.”


Conclusion

We can intercept the parameters sent from requests with the app.params method.

To listen to POST requests, we can use the app.post method. To listen to PUT requests, we can use the app.put method.

app.path lets us get the path of mounted apps.

app also has a long list of methods for listening to all kinds of requests.

Categories
JavaScript JavaScript Basics

How to Use the Array indexOf Method in JavaScript

The JavaScript array’s indexOf method returns the index of the first instance of a given entry when starting the search from the beginning of the array. Otherwise -1 is returned.

It takes up to 2 arguments. The first is the item to search for. The 2nd argument is an optional argument with the array index to start searching from.

The search is done by comparing the entry by using the === operator, which does comparison without type coercion beforehand.

For instance, we can use it as follows:

const index = [1,2,3].indexOf(2);

In the code above, we called indexOf on the array [1,2,3] with argument 2. This should return 1 and assign that to index since the first instance of 2 appears as the 2nd entry of the array.

We can also pass in an index number to the 2nd argument. For instance, we can write the following:

const index = [1, 2, 3].indexOf(2, 2);

index should be -1 in this case since we specified that we start searching from index 2 and beyond. 2 doesn’t exist in index 2 or beyond so -1 is returned.

Conclusion

indexOf lets search for an item in the array with either starting from the beginning or from a starting index.

It uses the === operator to compare each entry to find a match.

Categories
JavaScript JavaScript Basics

How to Check If a JavaScript String Contains a Substring

Checking if a JavaScript string contains a substring is easy. We can either use the includes method or we can use the indexOf method.

includes

To use the includes method, we can do that by writing the following code:

const hasFoo = 'foo bar'.includes('foo');

In the code above, we called the includes method on the string literal. It takes the substring to seacrh for in the first argument.

The 2nd argument, which is optional, is the position in the string to start the search from.

It returns true if the substring is found in the string that it’s called on and false otherwise.

In our example, we skipped the 2nd argument, so it’ll start searching from the beginning.

Therefore, hasFoo is true since 'foo' is in the string.

To search from a given index of the string that it’s called on, we can call it as follows:

const hasFoo = 'foo bar'.includes('foo', 5);

In the code above, it’ll start searching from index 5, which is past where 'foo' is. Therefore, it’ll return false and hasFoo is false.

indexOf

indexOf is another method that we can use to check if a substring is in a string. It takes the same arguments as includes but it returns the index of the first instance of the substring. If the substring isn’t found, then -1 is returned.

We can use it as follows:

const index = 'foo bar'.indexOf('foo');

We search for the 'foo' substring in the code above. Then indexOf returns 0 since 'foo' is at the beginning of the string.

Also, we can set the index to start searching from as follows:

const index= 'foo bar'.indexOf('foo', 5);

Then we get -1 for index since 'foo' is not found in any index from 5 or beyond.

Conclusion

We can call includes and index to check if a JavaScript string contains a given substring.