Moment.js blindspot
Bilal Collins
Posted on November 11, 2021
As a engineer, my daily tasks includes maintain code, and enhance some parts of it, and most of the time when i found an issue or a bug, specialy when it comes to data structure and algorithm, i see that the real issue is the library i prefer to use, because it helps me gain some time consuming calculation but with costs, and what i hate most is dealing with dates.
Straight to the point
Today, at late working hours, the CTO found a bug after an update to a subscription of one of our customers, and suddenly each subscription update after that cause a problem for others, after some hard minutes i see the line of code that hypothetically is the snake head of all the problems, and i can call it the moment.js blindspot.
Best thing is to give me an example
Imagine you are dealing with some dates like from when a subscription starts and when it's ends, when a payment must occurs …, evently you want to compare it to TODAY date, so you create a variable
const TODAY = moment();
and later on, you wich to subtract or add some days/hours/minutes to TODAY, so this hell that will burn all the parts of your app that depends on this "shitty" constant.
So to know that moment() is mutable and every variable depends on it, will edit the value of the first one (you can check mutable/immutable on javascript)
After i dig deeper on the code, i found that many parts that deals with subscriptions and payments, depends on TODAY, so when you run the server, TODAY will be shared among all uses, so each time you use it, it will save the result and will be used for the next statement.
Solutions
In anytime, you want to use a specific date (has meaning like in our example TODAY, it may be other value like moment(user.createdAt), …),
it's better to use one of this solutions:
1- Use the value everytime you want to re-use it
DON't
// payment process payment.process.js
let payment_due_date = TODAY.add(1, 'days).toDate();
// suspending process payment.suspend.js
let suspend_date = TODAY.add(1, 'months').toDate();
DO
// payment process payment.process.js
let payment_due_date = moment().add(1, 'days).toDate();
// suspending process payment.suspend.js
let suspend_date = moment().add(1, 'months').toDate();
2- moment.js comes with a helper function that can clone the constant-main value
// payment process payment.process.js
let payment_due_date = TODAY.clone().add(1, 'days).toDate();
// suspending process payment.suspend.js
let suspend_date = TODAY.clone().add(1, 'months').toDate();
This is my first article in the community, hope it will be more, i just want to share what i learned today, because it will cost you money, just for nothing.
Hope it will help, if you face the same issue, my advice is to read the documentation carfully of every library or module you integrate to your code.
Posted on November 11, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.