Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

moment is not a function - again #37

Closed
chambersDon opened this issue Aug 10, 2016 · 22 comments
Closed

moment is not a function - again #37

chambersDon opened this issue Aug 10, 2016 · 22 comments

Comments

@chambersDon
Copy link

I get an error at runtime that says: 'TypeError: moment is not a function'.

It's throwing the error on line 152: this.date = moment();.
I can see in the network tab that moment was downloaded successfully.

This is similar to issue #5 but I have followed those instruction and it's still not working.

I do not directly reference the node_modules files. Instead, I have a gulp file that moves what I need to the wwwroot folder (in a dotNet core application).

I don't get any compile errors with this import.
import {DatePicker} from 'ng2-datepicker';

I setup system.js so that ng2-datpicker points to ''ib/js/ng2-datepicker/src/components/ng2-datepicker' (note: this is the src - not the top level). At runtime it seems to find this JS but then crashes looking for moment.

I did the same for moment ('moment': 'lib/js/moment/moment') and I see the files are there but this is not working. It's finding moment so I'm not sure what the error is.

@jkuri
Copy link
Contributor

jkuri commented Aug 10, 2016

Hi, try to set SystemJS configuration for moment to look at ng2-datepicker/node_modules.

@chambersDon
Copy link
Author

chambersDon commented Aug 11, 2016

There is no node_modules folder under ng2-datepicker. The only folder is src and, in it is components. I'm using version 0.8.0.
By looking at other issues it appears that moment is included with the bundles but I don't see the bundles.

@jkuri
Copy link
Contributor

jkuri commented Aug 11, 2016

Then correctly set SystemJS path to moment, check in node_modules where is the source of moment and set it accordingly.

@chambersDon
Copy link
Author

chambersDon commented Aug 11, 2016

It's correctly set. I am using version 2.14.1.

Should I use a different version?
Is there an ng2-datepicker I can use that has moment bundled?

  • If I remove the system.js entry for moment it tries to look for moment.js in the root folder and returns a 404.
  • If I misspell the system.js entry I also get a 404.
  • When it's set correctly I see a status 200 in the network tab.

After I get the 200 for moment I get the error when I try to use the date picker. Here is the error:

browser_adapter.js:84 TypeError: moment is not a function
at DatePicker.init (ng2-datepicker.js:152)
at new DatePicker (ng2-datepicker.js:37)
at DebugAppView.View_RepairReturnComponent1.createInternal (RepairReturnComponent.template.js:608)
at DebugAppView.AppView.create (view.js:96)
at DebugAppView.create (view.js:308)
at TemplateRef
.createEmbeddedView (template_ref.js:64)
at ViewContainerRef_.createEmbeddedView (view_container_ref.js:106)
at NgIf.set as ngIf
at DebugAppView._View_RepairReturnComponent0.detectChangesInternal (RepairReturnComponent.template.js:48)
at DebugAppView.AppView.detectChanges (view.js:243)

@chambersDon
Copy link
Author

In my project I imported moment as:
import * as moment from 'moment';

and then used it like this:
var o = moment('11.08.2016', 'DD.MM.YYYY');

I got the same error: 'moment is not a function'.

Then I changed the import to:
import moment from 'moment';

And it worked.

ng2-datepicker uses this import: import * as moment from 'moment';

I don't see how this is the problem since everyone is not getting it.

This stack overflow post led me to this:
http://stackoverflow.com/questions/35272832/systemjs-moment-is-not-a-function

@jkuri
Copy link
Contributor

jkuri commented Aug 11, 2016

How do you set mappings in SystemJS configuration for moment?

@chambersDon
Copy link
Author

chambersDon commented Aug 11, 2016

var map = {
    'ng2-datepicker': 'lib/js/ng2-datepicker/src/components/ng2-datepicker',
    'moment': 'lib/js/moment/moment',
};

var packages = {
    'ng2-datepicker': { defaultExtension: 'js' },
    'moment': { defaultExtension: 'js' },
}; 

var config = {
defaultJSExtensions: true,
map: map,
packages: packages
}

@jkuri
Copy link
Contributor

jkuri commented Aug 11, 2016

Try

var map = {
  'ng2-datepicker': 'node_modules/ng2-datepicker',
  'moment': 'node_modules/moment'
}

var packages = {
  'ng2-datepicker': { main: 'ng2-datepicker', defaultExtension: 'js' },
  'moment': { main: 'moment', defaultExtension: 'js' }
}

Something like that, I think.

@chambersDon
Copy link
Author

My node_modules is not hosted. The content is moved to lib/js/ by a gulp script

I changed to this but still get the error.
var map = {
'ng2-datepicker': 'lib/js/ng2-datepicker/src/components',
'moment': 'lib/js/moment'
};

// packages tells the System loader how to load when no filename and/or no extension
var packages = {
    'ng2-datepicker': { main: 'ng2-datepicker', defaultExtension: 'js' },
    'moment': { main: 'moment', defaultExtension: 'js' }

}

My only difference is the path the files. I have verified they are there and I see moment load in the network tab.

@jkuri
Copy link
Contributor

jkuri commented Aug 11, 2016

I'll try to configure this with SystemJS and let you know.

@jkuri
Copy link
Contributor

jkuri commented Aug 11, 2016

Is there a reason why you don't have node_modules in the root and manually copying to lib/js? I believe that's not the right way as any 3rd party package installed is importing from "own" node_modules. In your case you should change path in ng2-datepicker.component.ts to

import * as moment from '../../moment';

But that's not the right way though.

@chambersDon
Copy link
Author

This was the recommend way for a dotNet core project. They have a wwwroot folder for everything you want to host. By default, the npm packages install in node_modules outside of this hosted folder.

I have several third party applications and they work - ng2-select, ng2-bs3-modal, ng2-file-upload, ng2-ckeditor, etc.

I don't think I need to change the location of moment in the import. With the system.js config it can find it by just calling it moment. I have verified it with the network tab. Also, I have used moment (as a test) in my application with this import: "import moment from 'moment';"

I changed your source to:
import moment from 'moment';
on line 13 and now it's working. I don't think that's a good long term solution.

@jkuri
Copy link
Contributor

jkuri commented Aug 11, 2016

No, that's not a solution. Still not sure if manually copying files from node_modules is good, too.

Not sure how npm works but I think that it's smart enough to have linked packages that are required by multiple packages and have them in separate node_modules where module is installed, so they find the correct way when importing.

Didn't checked if this is a reccomended way of a dotNet core project but I personally think this is wrong.

@chambersDon
Copy link
Author

I can look into changing it but they application has been in work for sometime. I'm not sure why the location of the files would matter if we are finding them.

@chambersDon
Copy link
Author

chambersDon commented Aug 24, 2016

I changed my application to use the hosted node_modules as you suggested. It didn't help - I still have the problem. I reverted back to my normal structure.

The runtime error is: "moment is not a function".
Line 14 of ng2-datepicker.ts is throwing the error: import * as moment from 'moment'.

My research indicates that when you import * a new object is created with the properties and functions and we want the original moment object like this. When I change the line to: import moment as moment from 'moment' the problem is resolved.

Here is another directive with this problem and the same fix:
valor-software/ngx-bootstrap#252

Here is a stack overflow post:
http://stackoverflow.com/questions/35272832/systemjs-moment-is-not-a-function

Any ideas?

@jkuri
Copy link
Contributor

jkuri commented Aug 24, 2016

Hey @chambersDon, I just used this component a couple of days ago and everything works fine. Please check again the README and come back with questions if it still won't work.

@chambersDon
Copy link
Author

I have reviewed the readme and I don't see any differences from what I have done. What specifically do you think I missed?

  1. I import like this: import {DatePicker} from 'ng2-datepicker/ng2-datepicker';
  2. I added DatePicker as a directive.
  3. My mark-up is this:
    <datepicker [(ngModel)]="model.quoteExpirationDate" view-format="DD.MM.YYYY" model-format="YYY-MM-DD" init-date="2017-05-12">

It builds with no problem. Then at runtime I get: TypeError: moment is not a function.

Also, I can't access your demo here: http://ng2-datepicker.jankuri.com
Is it still there?

@jkuri
Copy link
Contributor

jkuri commented Aug 25, 2016

I know, I am moving demos to other VPS. Please give me your SystemJS config and I'll take a look what can be done.

@chambersDon
Copy link
Author

(function (global) {

// map tells the System loader where to look for things
var map = {
    'app': 'lib/spa', // 'dist',
    'rxjs': 'lib/js/rxjs',
    'angular2-in-memory-web-api': 'lib/js/angular2-in-memory-web-api',
    '@angular': 'lib/js/@angular',
    'ng2-file-upload': 'lib/js/ng2-file-upload/ng2-file-upload',
    'ng2-ckeditor': 'lib/js/ng2-ckeditor/lib/ckeditor',
    'ng2-bs3-modal': 'lib/js/ng2-bs3-modal',
    'ng2-select': 'lib/js/ng2-select/ng2-select',
    'ng2-datepicker/ng2-datepicker': 'lib/js/ng2-datepicker/src/components/ng2-datepicker',
    'moment': 'lib/js/moment/moment',
    'angular2-notifications': 'lib/js/angular2-notifications'
};

// packages tells the System loader how to load when no filename and/or no extension
var packages = {
    'app': { main: 'boot.js', defaultExtension: 'js' },
    'rxjs': { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { defaultExtension: 'js' },
    '@angular': { defaultExtension: 'js' },
    'ng2-file-upload': { defaultExtension: 'js' },
    'ng2-ckeditor': { defaultExtension: 'js' },
    'ng2-select': { defaultExtension: 'js' },
    'ng2-datepicker/ng2-datepicker': { defaultExtension: 'js' },
    'moment': { defaultExtension: 'js' },
    'angular2-notifications': { main: 'components.js', defaultExtension: 'js' }
}; 

var packageNames = [
  '@angular/common',
  '@angular/compiler',
  '@angular/core',
  '@angular/http',
  '@angular/platform-browser',
  '@angular/platform-browser-dynamic',
  '@angular/router',
  '@angular/router',
  '@angular/testing',
  '@angular/upgrade',
  '@angular/forms'
];

// add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function (pkgName) {
    packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});

var config = {
    defaultJSExtensions: true,
    map: map,
    packages: packages
}

// filterSystemConfig - index.html's chance to modify config before we register it.
if (global.filterSystemConfig) { global.filterSystemConfig(config); }

System.config(config);

})(this);

@jkuri
Copy link
Contributor

jkuri commented Aug 31, 2016

Hey @chambersDon, can you try new 0.8.2? I made a minor change importing a moment module. Sorry for late response btw.

@connecttheworld
Copy link

Closing this one out?

@jkuri
Copy link
Contributor

jkuri commented Sep 19, 2016

yeah, I believe so since there's no response. Closing.

@jkuri jkuri closed this as completed Sep 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants