0

I have numerous scheduling task functions that rely on numerous convenience variables for datetime values in my project e.g. imagine 10 + lines like this:

let today = moment(),
  yesterday = moment().subtract(1, 'days'),
  startOfToday = moment(today).startOf("day"),
  endOfToday = moment(today).endOf("day");

I can't put this kind of initialization code at the top of the myCode.js file as it leads to a bug -- the functions within myCode.js will reference stale datetimes. e.g. today will always refer to the datetime the node server started.

For now I'm initializing dates within each function, but this leads to code duplication.

Is there a cleaner way to do this?

Options I'm considering:

a) Create a function that initializes all commonly used dates and invoke that at the top of the function.

b) inline the moment.js datetime values and get rid of the convenience variables altogether (works but makes code harder to read).

Tips appreciated,

Thanks,

-S. Arora

sarora
  • 913
  • 9
  • 20
  • 1
    what about making a custom object and expose those variables as class variables and then initialize them in the constructor? something like var convenienceVariables = new ConvenienceVariables(); convenienceVariables.yesterday, convenienceVariables.startOfToday, etc. etc. – victor Oct 05 '18 at 17:14
  • Why don't you create thunks and convert convenience variables to convenience functions? let today = ()=>moment(), yesterday =()=> moment().subtract(1, 'days'), startOfToday = ()=> moment(today()).startOf("day") and so on? – Shyam Babu Oct 05 '18 at 17:53
  • yes, that's what i did in the stackblitz reference below. the accepted answer suggests doing that and more. – sarora Oct 07 '18 at 22:08

1 Answers1

1

One way to do this would be to create an util module with all these convenience methods in there which then you can import in any of the files you need them.

Since your output is always date you can have one getDate method which would accept a string:

getDate('yesterday')
getDate('endOfToday')

This way it is pretty readable what you are trying to do and in that utils module you can simply have a switch statement which based on the string you return the proper date output:

switch(dateString) {
  case 'today':
     return moment()
  case 'yesterday':
     return moment().subtract(1, 'days')
...
}

If you do not like passing strings (although moment does that a lot) you can create an frozen class in ES6 to simulate an enumeration and pass/work with that.

You could also create a singleton class which has those and use that ... main idea is to have one method to return you the dates ... factory pattern.

Akrion
  • 18,117
  • 1
  • 34
  • 54
  • 1
    Thanks for this! As you were writing it i was playing with a similar solution here: https://stackblitz.com/edit/js-krggdi . Since i wanted to avoid re-initialzing all 10 dates over and over in each function that may need just a few dates, i went in the direction of creating convenience functions that return the desired value when invoked only. Your solution is very clean and relies on function as well so will glady accept it! – sarora Oct 05 '18 at 18:05
  • Awesome! glad it helped. Yeah there are more than few ways to achieve this so it is all about what works for you best. – Akrion Oct 05 '18 at 18:10