javascriptmathcheeriochaining

Chain method from function


Trying to understand chinning method, can be math like, cheerio/jQuery like, gonna shorten and replace with my own methods when things get too long.

//It will help me get shorten methods in complex methods and apply to a project

function getValue() {  
    this.add = function(y) {
        return x + y;
    };

    this.mult = function(y) {
        return x * y;
    };

    return this;
};

// not using instance from new operator will interesting

const price1 = getValue(8);
const price2 = getValue(2).add(1);
const price3 = getValue(5).add(3).mult(2);

//not important, but pushing further:
const price4 = getValue().add(2).add(2);
const price5 = getValue(5).add(2).add(2);

console.log(price1); // expect 8
console.log(price2); // expect 3
console.log(price3); // expect 16
console.log(price4); // expect 4
console.log(price5); // expect 9

Solution

  • You need getValue to take a parameter of x. Also, your chaining functions should return this. Lastly, you need a function to unwrap the value i.e. value().

    Note that in price4, you do not pass an initial value, so you can default to 0.

    function getValue(x = 0) {
      this.x = x;
      this.add = function(y) {
        this.x += y;
        return this;
      };
      this.mult = function(y) {
        this.x *= y;
        return this;
      };
      this.value = function() {
        return this.x;
      };
      return this;
    };
    
    const price1 = getValue(8).value();
    const price2 = getValue(2).add(1).value();
    const price3 = getValue(5).add(3).mult(2).value();
    const price4 = getValue().add(2).add(2).value();
    const price5 = getValue(5).add(2).add(2).value();
    
    console.log(price1); // expect 8
    console.log(price2); // expect 3
    console.log(price3); // expect 16
    console.log(price4); // expect 4
    console.log(price5); // expect 9

    Lodash's _.chain works like this:

    const price1 = _.chain(8).value();
    const price2 = _.chain(2).add(1).value();
    const price3 = _.chain(5).add(3).multiply(2).value();
    const price4 = _.chain().add(2).add(2).value();
    const price5 = _.chain(5).add(2).add(2).value();
    
    console.log(price1); // expect 8
    console.log(price2); // expect 3
    console.log(price3); // expect 16
    console.log(price4); // expect 4
    console.log(price5); // expect 9
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

    To make your code more re-usable, define top-level methods, ad call them inside the chain:

    const
      _add = (a = 0, b = 0) => a + b,
      _mult = (a = 1, b = 1) => a * b,
      _chain = (x) => ({
        _x: x,
        add: function(y) {
          this._x = _add(this._x, y);
          return this;
        },
        mult: function(y) {
          this._x = _mult(this._x, y);
          return this;
        },
        value: function() {
          return this._x;
        }
      });
    
    const Util = {
      add: _add,
      mult: _mult,
      chain: _chain
    };
    
    // With chain...
    console.log(Util.chain(8).value() === 8); // true
    console.log(Util.chain(2).add(1).value() === 3); // true
    console.log(Util.chain(5).add(3).mult(2).value() === 16); // true
    console.log(Util.chain().add(2).add(2).value() === 4); // true
    console.log(Util.chain(5).add(2).add(2).value() === 9); // true
    
    // On their own...
    console.log(Util.add(4, 7) === 11); // true
    console.log(Util.mult(4, 7) === 28); // true
    .as-console-wrapper { top: 0; max-height: 100% !important; }

    Here is how to extend jQuery by creating a plugin:

    (function($) {
      $.incrementNumericValues = function(text) {
        return text.replace(/\d+/g, function(n) {
          return parseInt(n, 10) + 1;
        });
      };
      $.fn.incrementNumericValues = function() {
        this.text($.incrementNumericValues(this.text())); // piggy-back
        return this; // Always return the jQuery object, unless computing/getting value
      };
    })(jQuery);
    
    // Can be called like this, but it's ugly
    $('#foo').text($.incrementNumericValues($('#foo').text()));
    
    // Chainable
    $('#foo').incrementNumericValues().css({ background: 'yellow' });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="foo">It's been 2 days since the last 13 days.</div>