How to test if a variable is a Moment.js object?
Asked Answered
A

5

107

My application has an HTML form with some inputs populated from the backend and other inputs being entered by the user (in a time input). An onChange function runs through each input when the user changes a value.

The inputs populated from the backend are converted to moment objects, the user-entered dates are mere strings. This means the onChange function encounters some moment objects, and some strings. I need to know which inputs are moment objects and which aren't.

What's the recommended method for testing if a variable is a moment object?

I've noticed moment objects have a _isAMomentObject property but I'm wondering if there's another way to test if a variable is a moment object.

Another option I've tried is calling moment on the variable regardless. This converts the string variables to moment objects and doesn't seem to effect existing moment objects.

Apologetic answered 6/4, 2016 at 16:38 Comment(0)
P
117

Moment has an isMoment method for just such a purpose. It is not particularly easy to find in the docs unless you know what to look for.

It first checks instanceof and then failing that (for instance in certain subclassing or cross-realm situations) it will test for the _isAMomentObject property.

Plutocracy answered 6/4, 2016 at 16:45 Comment(2)
what if it's not strongly typed? moment.isMoment(input);Noshow
@DonThomasBoyle this is JavaScript: there is no strong typing. 'Strong' is kind of an ambiguous term for typing, but by pretty much any possible definition (other than perhaps memory safety) JS types are weak. The only way that you can have that blow up is if input is null or undefined, literally any non-null JS object or even primitive value will just return a boolean.Plutocracy
G
40

You can check if it is an instanceof moment:

moment() instanceof moment; // true
Groping answered 6/4, 2016 at 16:44 Comment(3)
Only if the instance and moment itself are in the same window.Roaring
This is always true, because moment() would always create a moment object. Did you instead mean "obj instanceof moment;" ?Leroy
The danger of using instanceof is that the instance might be created from one moment dependency but will test against the moment function from another dependency. I.e. this will break if the code that created the moment object used another creation function than the code that tests. An example of when this can happen is if the code that runs the test above is in a separate npm package that depends on another version of moment.Smothers
P
3

moment() instanceof moment;

will always be true, because if you have

  • moment(undefined) instanceof moment
  • moment("hello") instanceof moment

you are always creating a moment object. So the only way is to check like this

  • moment(property).isValid()
Passport answered 24/8, 2018 at 8:40 Comment(1)
I think you meant to make a comment to Niels' answer.Huth
H
0

While technically all upvoted responses are true and are the way to go, in my particular case @Anang Sartia's answer worked.

I had a Shared packages library and two downstream apps that were importing the package library. One downstream app migrated from MomentJS to Date-FNS (that works with plain JS Date objects), while the other still remained with Moment. The reason to migrate from Moment was primarily due to large bundle size and the fact that MomentJS doesn't suport tree-shaking (and other disadvantages provided by MomentJS team here https://momentjs.com/#:~:text=Considering%20using%20Moment,in%20the%20docs.

The Shared packages had a method that was transforming plain objects. Dates were not falling into that criteria. So because Dates and Moment are also objects, they had to be ignored. Using moment.isMoment(obj) implied that Shared packages also need to install Moment.JS just to check for this particular case. And because Moment.JS is not tree-shakable, it was not a great idea to import moment just for a single moment method.

In my case I created a helper method that checks for _isAMomentObject property. isValid property remarked by @Anang Satria could be present in any regular object. On the other hand, any valid Moment object has this unique property _isAMomentObject. Doing so, in my case solved the issue.

export function isMomentObject(obj: any): boolean {
  return !!obj._isAMomentObject;
}

To summarize:

If you already have defined MomentJS as the dependency then moment.isMoment(obj) is the way to go. If you don't want to import moment, but somehow you get Moment objects and you want to treat them differently, then you should consider the provided alternatives.

Hexastyle answered 6/12, 2023 at 10:55 Comment(0)
M
-1

Pretty similar to the answer by @Fabien, I'm checking the object if the isValid function is available.

const checkMoment = (date) => {
    if(!date.isValid){ // check if it's not a moment object
        // do something if it's not moment object
        console.log('this is not a moment object');
    }
    else {
        // do something if it's a moment object
        console.log('this is a moment object');
    }
   
}
Manned answered 4/11, 2021 at 8:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.