Hi, I'm trying to use chart.js and moment.js using requireJS, but I always get the following error:
Error: Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com
I can use Chart.bundle.js and it works but I can't use moment from it, so I need to import it independently.
I've tried to find any example on the web without success. And the docs says that:
The Chart.bundle.js and Chart.bundle.min.js builds include Moment.js in a single file. This version should be used if you require time axes and want a single file to include, select this version. Do not use this build if your application already includes Moment.js. If you do, Moment.js will be included twice, increasing the page load time and potentially introducing version issues.
But the examples in the repository import it twice...
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../../dist/Chart.bundle.js"></script>
Thanks
@adrianhurt is it possible to create a fiddle with this for debug purposes?
Sure!
First, I've adapted one of the examples to use RequireJS. It uses moment.js and Chart.bundle.js so moment it's imported twice:
http://codepen.io/adrianhurt/pen/ZOyKqJ
And then I've tried to change Chart.bundle to Chart but it doesn't work.
http://codepen.io/adrianhurt/pen/dXRRoL
I always get the error
Error: Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com
Even setting moment as a dependency of Chart.
I suppose I'm missing some stupid thing, but I can't find any example using RequireJS.
Thanks!
Looks like this is because of require. The chart factory doesn't apparently get passed the moment object returned from the factory. Since it can't find it, it defaults to window.moment which does not exist.
One solution to this would be to build using webpack or browserify since then all the dependencies would be included.
Thank you. I've noted you marked this issue as a bug, so I suppose it will be fixed. My project is now in development so meanwhile I'll use it with Chart.bundle.js and moment.js as well. Thank you for your help and for the library!
Same problem with angular-cli (SystemJS) and Angular 2.
It appears Chart.bundle.js does not attach moment globally to the window object?
I think it's exactly that
with requireJS you would load moment.js like this
require(['moment','chartjs'], function(moment, Chart) {
var c = new Chart(...);
});
So inside that callback, the moment object is available but not globally (window.moment). And if you try to assign it to window.moment manually inside the callback, its too late because Chartjs has already been initialized by the time we get there.
What is missing is way to pass the moment to Charts.js.
For example
require(['moment','chartjs'], function(moment, Chart) {
// manually initialize moment
Chart.moment = moment;
// create charts...
var c = new Chart(...);
});
The actual moment "object" is not used until the time scale is initialized, yet chart.js wants it to be available at initialization time?
Here is a workaround for requireJS which doesn't involve modifying chartjs.
Create moment-fix.js which pre-loads moment.js and adds it to the global scope.
/*
* moment-fix.js
*
* Assign reference to moment at global scope to let ChartJS use window.moment.
*/
define(['moment'], function (moment) {
// assign moment to global window object
window.moment = moment;
});
Setup a shim in your requireJS configuration to load moment-fix before chartjs.
require.config({
waitSeconds: 0,
shim: {
'chartjs': {deps: ['lib/chartjs/moment-fix']},
'bootstrap': {deps: ['jquery']}
},
paths: {
'jquery': 'lib/jquery/jquery-2.2.3.min',
'bootstrap': 'lib/bootstrap/bootstrap',
'cookies': 'lib/cookie/js.cookie',
'i18next': 'lib/i18n/i18next.amd-1.11.1.min',
'moment': 'lib/moment/moment-config',
'chartjs': 'lib/chartjs/Chart'
}
});
Is this still causing an error or can this issue be closed?
@zachpanz88 Pretty sure this issue still exists. The requirejs shim solution is alright, but making the factory pattern logic more robust still seems like the right permanent fix.
Any progress on this issue? It still persists for me.
This problem happens to me at src/scales/scale.time.js on line 7
moment = typeof(moment) === 'function' ? moment : window.moment;
when I tried to use time series on XAxis.
Console.log the moment object I can see that moment variable is a es6Module as below, whose default is a function and what the file actually wants.
console.log(moment) -> {__esModule: true, default: Æ’}
Currently typeof(moment) === 'function' returns false and moment points to window.moment which is undefined. Hence the error "Chart.js - Moment.js could not be found!".
Solution:
Update the line in node_modules/chart.js/src/scales/scale.time.js to below works for me.
moment = typeof(moment.default) === 'function' ? moment.default : window.moment;
Comment:
I've seen this error frequently when one module "require" an es6 module in an es5 way. "Import" should work fine without the ".default". Please comment if I'm wrong.
Versions:
chart.[email protected]
[email protected]
I have the same issue of @chrisli30 with Ionic 3.
I removed all usage of momentjs in favor of date-fns in my Angular 5 (+ angular-cli) app only to realize that Chartjs depends on Momentjs.
This should've been fixed long time ago. Any progress?
Most helpful comment
Here is a workaround for requireJS which doesn't involve modifying chartjs.
Create moment-fix.js which pre-loads moment.js and adds it to the global scope.
Setup a shim in your requireJS configuration to load moment-fix before chartjs.