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

Upvotes: 0

Views: 88

Answers (2)

JACKSON MUIRU
JACKSON MUIRU

Reputation: 101

I have improved the above code by add default value to y to prevent the result to "nan" when y is not provided. Overall its a great answer.

function getValue(x = 0) {
  this.x = x;
  this.add = function(y = 0) {
    this.x += y;
    return this;
  };
  this.mult = function(y = 1) {
    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

Upvotes: 0

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48713

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>

Upvotes: 2

Related Questions