JavaScript Chaining
Tags: javascript, programming, webdev, chaining
Published: 2023-11-23 13:38:43

## INTRO 🔊
Chaining is the concept one function returns a current(`this`) object and another function will use values in that current(`this`) object. It's the same as [PIPELINE](https://dev.to/sundarbadagala081/javascript-pipeline-4d27) explained in my previous post. But the difference is in chaining we have pre-defined methods not like a pipeline. Javascript chaining is a very familiar concept. If you know array methods then you automatically know javascript chaining. 

## DEFINITION 🔊
Method Chaining is a programming strategy that simplifies and embellishes your code. It is a mechanism for calling a method on another method of the same object.

## USAGE 🔊
For example, if we want to use one `method/function` modified value in another method/function every time we have to call that method/function and have to pass the returned value from the previous function to the next method/function. It leads to more code, lacks the best practice and affects the performance. 

## EXAMPLE 🔊
For example let's take four functions named `add`, `subtract`, `divide`, `multiple`. We have to use the value returned from the function `add` into `subtract`, later we have to use the returned value from `subtract` into `divide`, and in that same way, we have to use the returned value from `divide` into `multiple` and finally should be return the value.

**WITHOUT CHAIN** 🔕

```javascript
const add=(i,num )=>{
   return i + num //16
}

const subtract=(i, num)=>{
   return i - num //12
}

const divide=(i, num)=>{
   return i / num //4
}

const multiple=(i, num)=>{
   return i * num //8
}

let x = 10
const a = add(x, 6)
const b = subtract(a, 4)
const c = divide(b, 3)
const res = multiple(c, 2)

console.log(res)
```
If you observe the above code we wrote all 4 methods individually and defined them one by one. It takes up more space and code is also not much readable.

```javascript
const add=(num, a)=> {
   return num + a
}
const subtract=(num, a)=>{
   return num - a
}
const divide=(num, a)=>{
    return num / a
}
const multiple=(num, a)=>{
   return num * a
}

const res = multiple(divide(subtract(add(10, 6), 4), 3), 2)

console.log(res)  //8
```
By using the Higher Order Function method, the code is not readable and it's taking right to left format (usually the code should be in left to right format) which is a little bit confusing.

```javascript
const add=(callback, num)=> {
    return callback(num + 6)
}
const subtract=(callback, a)=>{
    return callback(a - 4)
}
const divide=(callback, a)=>{
    return callback(a / 3)
}
const multiple=(callback, a)=>{
    return callback(a * 2)
}

const res = add((a)=>{
    return subtract((b)=>{
      return multiple((c)=>{
          return divide((d)=>{
             return d
          }, c)
      }, b)
    }, a)
}, 10)

console.log(res)
```
With the callback method, It creates callback hell, not readable and not very efficient.

**WITH CHAIN** 🔔
```javascript
function main(num) {
  let i = num;
  return {
    add: function (num) {
      i += num;
      return this;
    },
    subtract: function (num) {
      i -= num;
      return this;
    },
    divide: function (num) {
      i /= num;
      return this;
    },
    multiple: function (num) {
      i *= num;
      return this;
    },
    print() {
      return i;
    },
  };
}

const x = main(10)
const res = x.add(6).subtract(4).divide(3).multiple(2).print();

cosole.log(res)
```
The above code is very readable and we can consider it as the best practice method compared to the previous one.

## DIFFERENT WAYS TO ACHIEVE CHAINING IN JAVASCRIPT 🔊

**FACTORY FUNCTIONS** 📕
```javascript
function main(num) {
  let i = num;
  return {
    add: function (num) {
      i += num;
      return this;
    },
    subtract: function (num) {
      i -= num;
      return this;
    },
    divide: function (num) {
      i /= num;
      return this;
    },
    multiple: function (num) {
      i *= num;
      return this;
    },
    print() {
      return i;
    },
  };
}

const x1 = main(10);
const x2 = main(10);

const value = x1.add(6).subtract(4).multiple(3).divide(2).print();
const value2 = x2.multiple(3).add(6).subtract(4).divide(2).print();
const value3 = x2.multiple(5).divide(4).print()

console.log(value);     //18
console.log(value2);    //16
console.log(value3)     //20
```

**CONSTRUCTOR FUNCTIONS** 📗
```javascript
const main = function (init = 0) {
  this.i = init;
  this.add = function (i) {
    this.i += i;
    return this;
  };
 this.subtract = function (i) {
    this.i -= i;
    return this;
  };
  this.multiple = function (i) {
    this.i *= i;
    return this;
  };
 this.divide = function (i) {
    this.i /= i;
    return this;
  };
  this.print = function () {
    return this.i;
  };
};

const x1 = new main(10);
const x2 = new main(10);

const value = x1.add(6).subtract(4).multiple(3).divide(2).print();
const value2 = x2.multiple(3).add(6).subtract(4).divide(2).print();
const value3 = x2.multiple(5).divide(4).print()

console.log(value);     //18
console.log(value2);    //16
console.log(value3)     //20
```

**CLASS METHODS** 📘
```javascript
class Main {
  constructor(data) {
    this.data = data;
  }
  add(num) {
    this.data += num;
    return this;
  }
  subtract(num) {
    this.data -= num;
    return this;
  }
  divide(num){
      this.data /= num;
      return this;
  }
  multiple(num) {
    this.data *= num;
    return this;
  }
  print() {
    return this.data;
  }
}

const x1 = new Main(10);
const x2 = new Main(10)

const value = x1.add(6).subtract(4).multiple(3).divide(2).print();
const value2 = x2.multiple(3).add(6).subtract(4).divide(2).print();
const value3 = x2.multiple(5).divide(4).print()

console.log(value);     //18
console.log(value2);    //16
console.log(value3)     //20
```

**OBJECT METHODS** 📙
```javascript
const main = {
  data: {
    i: 0,
  },
  initiate: function (num = 0) {
    this.data.i = num;
    return this;
  },
  add: function (num) {
    this.data.i += num;
    return this;
  },
  subtract: function (num) {
    this.data.i -= num;
    return this;
  },
  multiple: function (num) {
    this.data.i *= num;
    return this;
  },
  divide: function (num) {
    this.data.i /= num;
    return this;
  },
  print: function () {
    return this.data.i;
  },
};

const value = main.initiate(10).add(6).subtract(4).divide(3).multiple(2).print();
const value2 = main.initiate(10).multiple(3).add(6).subtract(4).divide(2).print();

console.log(value);     //8
console.log(value2)     //16
```

## SIMILAR TO ARRAY METHODS 🔊
If you observe array methods like `map`, `filter`, `reduce` etc... they are also follows the same code practice 

For Example :-
```javascript
Array.map().filter().reducer()
```


## CONCLUSION 🔊
Chaining is the one of the best practice method for create multiple methods depends on one on another. same like array methods. It looks clean and readable. So from now onwards if we want to write multiple dependent methods, follow the chaining method 😎

Peace 😊