Karthik Chintala
Karthik Chintala

Reputation: 5545

Javascript returning value if no method chaining is available

I'm just getting started with the method chaining concept in javascript. I'm aware of returning this to chain methods but I'm using revealing module pattern here.

Code:

var currency = (function(){
    var rates = {
        INR: 64.10
    };

    function convert(value){
        return value * rates["INR"];
        //"return this"? and also get the return value (if no chained mathods) ?
    }

    function format(){
        return this.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
    }

    return {
        convert: convert,
        format: format
    }
})();

I'll call the function in two different ways.

  1. currency.convert(100); //6410; right now it returns rate and this is expected
  2. currency.convert(1000).format(); //64,100; this is expected

But the problem is if I return this; from the convert function how would #1 be possible? If I don't return this from the convert function method chaining won't be possible.

Q: convert() function in this pattern should be able to perform conversion and return the value if no chaining is requested and should be able to perform chaining?

Please ignore if the format function wrong.

Upvotes: 0

Views: 1197

Answers (1)

riyaz-ali
riyaz-ali

Reputation: 9102

As mentioned in the comments, the pattern you showed in the OP is not suited for chaining. But what you are trying to achieve is absolutely fine. Look through the embedded script to see how this can be done

let CurrencyConverter = (function() {
  const rates = {
    INR: 64.10
  }
  
  // CurrencyConverter class
  function CurrencyConverter() {
    // instantiate with new
    // 'this' inside this function is the new instance
    // of CurrencyConverter
    this.value = 0;
  }

  // Add convert method
  // this method just convert the value and store it
  CurrencyConverter.prototype.convert = function convert(value) {
    this.value = value * rates["INR"];
    return this;
  }

  // Add format method
  // this method formats the rate and 
  // return the formatted output
  CurrencyConverter.prototype.format = function format() {
    return (this.value + "").replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
  }
  
  // add as many more methods as you want
  // ...
  
  // finally return the 'class'
  return CurrencyConverter;
})()

// instantiate new converter
let converter = new CurrencyConverter();

// convert
console.log(converter.convert(75).format())

NOTE: The snippet above is not 100% perfect but it is there just to give an idea of how this can be achieved in javascript.

UPDATE - 1
Based on the comment, here is an alternate approach:

let converter = (function() {
  // constant rates
  const rates = {
    INR: 64.10,
    GBP: 1.29
  }

  // converter function
  return function convert(value, currency) {
    let _val = (value * rates[currency || "INR"]).toFixed(2)

    let ret = {}

    // value getter
    Object.defineProperty(ret, 'value', {
      get: () => _val
    });

    // value formatter
    Object.defineProperty(ret, 'formatted', {
      get: () => (_val + "").replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
    });

    return ret;
  }
})();

// use it like
console.log(converter(125).value)
console.log(converter(120, "GBP").formatted)

Upvotes: 2

Related Questions