Method Chaining in JavaScript



Method or function chaining is a popular method in JavaScript that is used to write more concise and readable code. In this article, we shall discuss the method of chaining tactics in JavaScript and also discuss how it works

In some JavaScript programs written with JQuery or some other packages, sometimes we call multiple functions one after another on the same line. This can be explained by a simple example as shown below −

Syntax

ob = <some object>
ob.method_1().method_2().(some more methods).method_n()

Example 

Without using the method of chaining.

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"></div> <div id="opError" style="color : #ff0000"></div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { let s = 'HELLO World JavaScript is Awesome' s = s.toLowerCase() s = s.replace(/ /g, '|') // globally replace all spaces with | s = s.trim() content += "Value of s: " + JSON.stringify(s) + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

Example

With Method Chaining −

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { let s = 'HELLO World JavaScript is Awesome' s = s.toLowerCase().replace(/ /g, '|').trim() content += "Value of s: " + JSON.stringify(s) + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

Example

With Method Chaining but the writing method in a different line −

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { let s = 'HELLO World JavaScript is Awesome' s = s .toLowerCase() .replace(/ /g, '|') .trim() content += "Value of s: " + JSON.stringify(s) + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

We can apply the same for an array where we want to use a few array methods one after another. Let us see the following example of method chaining on an array.

Example

On Array objects (Without method Chaining)

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { let arr = [10, 70, 30, null, 80, null, 0, null, '50', 150] arr = arr.filter(e => typeof e === 'number' && isFinite(e)) arr = arr.sort((x, y) => x - y) content += "The array elements are, after filtering: " + JSON.stringify(arr) + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

Example

On Array objects (With method Chaining) −

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { let arr = [10, 70, 30, null, 80, null, 0, null, '50', 150] arr = arr .filter(e => typeof e === 'number' && isFinite(e)) .sort((x, y) => x - y) content += "The array elements are, after filtering: " + JSON.stringify(arr) + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

Asynchronous function in JavaScript uses promises to work with. Promises are a very good example in this domain of method chaining. To implement promises we need to create the promise at first, then create appropriate handler functions. We need these handler functions to process the value after resolving the promise.

Example 

Using promise

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { // Create a new Promise object const p = new Promise((resolve, reject) => { // make a delay setTimeout(function () { // Resolve the promise by returning a message resolve('Message After Promise') }, 1000) }) .then( function (data) { content += "Data coming after resolving promise: " + JSON.stringify(data) + '<br>'; opDiv.innerHTML = content }) .catch(err => error += "Error Message: " + JSON.stringify(err) + '<br>') } catch (err) { error += err } finally { // display on output console opErrDiv.innerHTML = error } </script> </body> </html>

Creating Own Object for Method Chaining in JavaScript

In the previous few examples, we have seen how the method of chaining can be applied in the JavaScript program. Now we shall cover, how we can implement the same for our object. In this example, we will create one class type with multiple functions and they can be used by method chaining.

For method chaining, the ‘this’ keyword plays the actual role. As we know, the ‘this’ keyword points to the current object which is used.

Example 

Using promise

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const person = { name: 'Alice', age: 25, state: null, currentState() { content += "The current state: " + JSON.stringify(this.state) + '<br>' }, eatFood() { this.state = 'Eating food.' this.curentState() return this }, playCricket() { this.state = 'Playing Cricket' this.currentState() return this }, sleep() { this.state = 'Now Sleeping.' this.currentState() return this }, jump() { this.state = 'Jumping High.' this.currentState() return this }, walk() { this.state = 'Morning Walking.' this.currentState() return this }, doWork() { this.state = 'Doing my work.' this.currentState() return this } } person .sleep() .walk() .jump() .eatFood() .doWork() .sleep() } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

In this example, we can see the functions are returning the current object using the ‘this’ keyword. Without using that it will not qualify for method chaining. In the above example, the class person is holding a member variable called state. This state is updated whenever we are calling any function given in the class. In the end, they are called by method chaining to execute all at once.

Conclusion

Method chaining is an interesting feature in JavaScript, which helps to reduce the size of code and increase the readability of our code. In method chaining, we call separate methods of a single object like a chain without assigning the same object multiple times by assignment operators. Method chaining works well when we use asynchronous functions with promises. Sometimes we take data from a network which does not synchronous to our code. We have to wait for a certain period. In that case, there will be mainly two different cases where in one case we mention what will be done after processing the input, and the other case does what is needed if there is an error occurred.


Advertisements