0

I have been trying to find a way to have class parameter that can be formatted.

class Animal {
  this.dob: '2019-12-12';
  // Pseudo code
  format: (date, format) => formatDate(date, format);
}

const animal = new Animal();

when calling it: animal.dob I want to see '2019-12-12'

but if I want it formatted, I'd like to have the option to chain:

animal.dob.format('DD.MM) which would return '12-12'

My main reason for doing that is that at the moment I have format(animal.dob, 'DD.MM') littering my code all over the place and I would like to remove these calls as much as possible.

Any idea on how to achieve that?

Thanks in advance

Got The Fever Media
  • 750
  • 1
  • 9
  • 27

2 Answers2

0

You can't chain animal.dob.format like this because your animal.dob returns a string which doesn't have any method called format on it, Instead what you can do is pass the parameter to animal.format() and return values accordingly

class Animal {
  constructor(){
    this.dob = '2019-10-12';
  }
  format(date, format){
    let [YY,MM,DD] = date.split('-')
    let mapper={ YY, MM, DD }
    format = format.replace(/\./g,'-')
    return format.replace(/[^-]+/g,(m)=>mapper[m])
  }
}

const animal = new Animal();

console.log(animal.format(animal.dob, "MM.DD"))
console.log(animal.format(animal.dob, "YY.DD"))
console.log(animal.format(animal.dob, "YY.MM.DD"))
console.log(animal.format(animal.dob, "YY.DD.MM"))

If you don't want to pass date explicitly you can simply use this.dob instead of accepting a parameter date in format function

class Animal {
    constructor(){
      this.dob = '2019-10-12';
    }
    format(date, format){
      let [YY,MM,DD] = this.dob.split('-')
      let mapper={ YY, MM, DD }
      format = format.replace(/\./g,'-')
      return format.replace(/[^-]+/g,(m)=>mapper[m])
   }
}

const animal = new Animal();

console.log(animal.format("MM.DD"))
console.log(animal.format("YY.DD"))
console.log(animal.format("YY.MM.DD"))
console.log(animal.format("YY.DD.MM"))
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • 1
    While this doesn't reduce the boilerplate, it is a more sensible place for the code. It's also nice and clear. – christopher Sep 02 '19 at 11:54
  • But it adds code, and absolutely not answer my question. I would rather have a specific method on the class then `animal.formatBOD()`, than implementing that solution – Got The Fever Media Sep 02 '19 at 11:56
  • @GotTheFeverMedia well if you don't want to pass the date value explicitly you can simply use `this.dob` inside `format` function, read the last line in the answer isn't it what you're after ? – Code Maniac Sep 02 '19 at 11:59
  • but still, my question is about chaining potential formatting, not just the date – Got The Fever Media Sep 02 '19 at 12:01
  • @GotTheFeverMedia with the current type of `this.dob` it doesn't seems possible to me as far as i know, you need to change the structure of `this.dob` ? do you want that ? – Code Maniac Sep 02 '19 at 12:04
  • yes I can do that, however, if possible, `animal.dob` needs to return a value :D – Got The Fever Media Sep 02 '19 at 12:39
  • @GotTheFeverMedia [`Look at this`](https://jsbin.com/kefegiq/edit?js,console) you can do something like this, – Code Maniac Sep 02 '19 at 13:14
0

You can create an object from the string and add the format method to the instance. The string object can be used as normal string. Check this question for the differences.

class Animal {
  constructor() {
    this.dob = Object("2019-12-12"); // or new String("...")
    this.dob.format = function (format) {
      console.log(this.valueOf(), format);
    };
  }
}

const animal = new Animal();
animal.dob.format("DD.MM");
Object("Hello") + Object("World!") //=> "HelloWorld!"

If you use certain custom methods often consider creating your own class instead, extending from String.

class MyString extends String {
  format(format) {
    console.log(this.valueOf(), format);
  }
}

class Animal {
  constructor() {
    this.dob = new MyString("2019-12-12");
  }
}

const animal = new Animal();
animal.dob.format("DD.MM");

If you want to set dob after creation, considder adding a .setDob method, that accepts a string and converts it to an object with the needed methods. Alternatively you might want to look into setters.

Note: You don't need to call .valueOf() this converts the string object back to a native string. They behave the same. I only use it here because the console output is nicer. "foo" //=> "foo" while Object("foo") //=> { 0: "f", 1: "o", 2: "o" }

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
  • ah. thanks for that, I guess that's going in the right direction. Now calling `animal.dob.valueOf()` is a bit cumbersome but not too problematic. I could now have a getter for these computed values... – Got The Fever Media Sep 02 '19 at 12:42
  • @GotTheFeverMedia You don't need to, `animal.dob` behaves as a normal string. I only do it here because the `console.log` output is different. eg. `{ 0: "2", 1: "0", 2: "1", ... }` – 3limin4t0r Sep 02 '19 at 12:44
  • interesting. I tried in the console and yes it works well. Does that work with numbers too? – Got The Fever Media Sep 02 '19 at 12:46
  • @GotTheFeverMedia yes, see: [`Object()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) - "The `Object` constructor creates an object wrapper." – 3limin4t0r Sep 02 '19 at 12:46
  • Cool, let me try that in my code, if all goes well you'll be the answer – Got The Fever Media Sep 02 '19 at 12:47