46

I'm using JSPM, AngularJS, TypeScript, SystemJS and ES6 and my project is running pretty well... unless I try to use momentJS.

This is the error I get:

TypeError: moment is not a function

This is part of the code:

import * as moment from 'moment';

More:

var momentInstance = moment(value);

If I debug it, moment is an object not a function:

enter image description here

This is what my moment.js JSPM package looks like:

module.exports = require("npm:moment@2.11.0/moment.js");

I've read a lot and couldn't find a way to solve this... any ideas?

Some things I've read/tried:

How to use momentjs in TypeScript with SystemJS?

https://github.com/angular-ui/ui-calendar/issues/154

https://github.com/jkuri/ng2-datepicker/issues/5

Typescript module systems on momentJS behaving strangely

https://github.com/dbushell/Pikaday/issues/153

Thanks!

Community
  • 1
  • 1
eestein
  • 4,914
  • 8
  • 54
  • 93
  • who did you do your injection dependency of moment in angular ? – AlainIb Feb 08 '16 at 15:13
  • @AlainIb hi, thanks for your comment. I'm sorry, but do you mean why? If so, what would you recommend as an alternative? Thanks again. – eestein Feb 08 '16 at 15:15

6 Answers6

101

Simply remove the grouping (* as) from your import statement:

import moment from 'moment';

Without digging too deeply in to the source code, it looks like moment usually exports a function, that has all kinds of methods and other properties attached to it.

By using * as, you're effectively grabbing all those properties and attaching them to a new object, destroying the original function. Instead, you just want the chief export (export default in ES6, module.exports object in Node.js).

Alternatively, you could do

import moment, * as moments from 'moment';

to get the moment function as moment, and all the other properties on an object called moments. This makes a little less sense when converting ES5 exports like this to ES6 style, because moment will retain the same properties.

Oka
  • 23,367
  • 6
  • 42
  • 53
  • @eestein Cheers. Here's the MDN article on [`import`](https://developer.mozilla.org/en/docs/web/javascript/reference/statements/import). In my opinion, it's a little too brief right now, but it does cover most of the syntax. – Oka Feb 08 '16 at 15:39
  • 8
    I too had tried `import * as moment from 'moment'` which gave me the "moment is not a function" error. Changing it as you suggested to `import moment from 'moment'` just changes the error to `moment_1.default is not a function`. what is going on here? (It seems that changing the way I import has caused typescript to compile my `moment()` function call into a `moment_1.default` function call.) – uglycoyote May 12 '17 at 06:22
  • I had to add `"allowSyntheticDefaultImports": true` under *compilerOptions* in *tsconfig.json* file – emkarachchi Jul 15 '22 at 09:07
  • I came here when get runtime error `moment_1.default is not a function`. Then I changed `import moment from 'moment';` => `import * as moment from 'moment';` and this worked. – Leonid Pavlov Feb 08 '23 at 07:47
3

This worked for me:

import moment from 'moment/src/moment'
S. Bleier
  • 79
  • 4
0

A beginner JS mistake that was giving me the same error:

foobar(moment) {
  console.log(moment().whatever());
}

Naming a parameter moment breaks access to the moment() function.

Patrick
  • 1,227
  • 14
  • 17
0

AS plot in the official documentation momentJs my problems were solved via nodeJS approach:

var moment = require('moment');
moment(); //this does not emit the errors
Honza P.
  • 1,165
  • 1
  • 11
  • 12
0

To get moment work as a function, if you are using ES6 and babel, you must import it in this way:

import moment from 'moment'

and not, as written in the documentation

import * as moment from 'moment'
blazehub
  • 1,880
  • 19
  • 25
0

Remove this

import * as moment from "moment";

add this instead

import moment from "moment";

And that is how it is used in your context

{moment(finalOrder.order.order.order.dateOrdered).format("MM-DD-YYYY")}
Awara Amini
  • 307
  • 1
  • 6