4

I'm building an app with Durandal to bundle with PhoneGap. When I'm trying to run the weyland optimizer I'm running into some issues. The build and optimization runs fine without any errors (I'm using requirejs as optimizer), but when I run the application my kendo ui chart throws an error saying "Uncaught TypeError: Object [object Object] has no method 'kendoChart'".

If I pause in debug mode in chrome where the kendoChart binding is taking place and type "kendo" in the console I get the kendoobject and can view its properties and so on, so it's definitely in the DOM.

Iv'e google around quite a bit and found some threads here on SO but none of them seem to sort my issue out. For instance this thread or this one.

I have a custom knockout binding for the chart, which is provided below.

My weyland.config looks like this:

exports.config = function (weyland) {
weyland.build('main')
    .task.jshint({
        include: 'App/**/*.js'
    })
    .task.uglifyjs({
        // not uglyfying anything now...
        //include: ['App/**/*.js', 'Scripts/durandal/**/*.js', 'Scripts/custom/**/*.js']
    })
    .task.rjs({
        include: ['App/**/*.{js,html}', 'Scripts/custom/**/*.js', 'Scripts/jquery/*.js', 'Scripts/durandal/**/*.js'],
        exclude: ['Scripts/jquery/jquery-2.0.3.intellisense.js', 'App/main.js'],
        loaderPluginExtensionMaps: {
            '.html': 'text'
        },
        rjs: {
            name: 'main',
            baseUrl: 'App',
            paths: {
           'text': '../Scripts/text',
           'durandal': '../Scripts/durandal',
           'plugins': '../Scripts/durandal/plugins',
           'transitions': '../Scripts/durandal/transitions',

           'knockout': '../Scripts/knockout/knockout-2.3.0',
           'kendo': 'empty:', <-- tried refering kendo.all.min, or dataviz.chart or the path
           'jquery': '../Scripts/jquery/jquery-2.0.3.min',
           'Helpers': '../Scripts/custom/helpers',


                 ........ other scripts ......
            },
            deps: ['knockout', 'ko_mapping', 'command'],
            callback: function (ko, mapping, command) {
                ko.mapping = mapping;
            }
            //findNestedDependencies: true, **<-- tried both true and false here**
            inlineText: true,
            optimize: 'none',
            pragmas: {
                build: true
            },
            stubModules: ['text'],
            keepBuildDir: false,
            out: 'App/main-built.js'
        }
    });
 };
    // The custom binding for the kendo chart
define([
    'knockout',
    'jquery',
    'Helpers',
    'kendo/kendo.dataviz.chart.min'
    ], function (
    ko,
    $,
    helpers,
    kendoui
    ) {
    function drawChart(element, values, options) {
        $(element).kendoChart({ **<-- this is where I get an error**
            ... options for chart ...
        });
    }

// kendoUi data viz chart
ko.bindingHandlers.moodChart = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        //set the default rendering mode to svg
        kendo.dataviz.ui.Chart.fn.options.renderAs = "svg";  **<-- this renders no errors**
        // if this is a mobile device
        if (kendo.support.mobileOS) {
            // canvas for chart for you!
            kendo.dataviz.ui.Chart.fn.options.renderAs = "canvas";
        }

        var values = ko.unwrap(valueAccessor());

        setTimeout(function () {
            drawChart(element, values);
        }, 125);
    }
};
});

I might add that everything works fine running the not optimized code in a web browser (or a phone for that matter).

I've also tried to shim the kendo path in the config file and add a dependency to jquery, which doesn't really seem to do any difference.

Any help would be appreciated!

Community
  • 1
  • 1
aup
  • 800
  • 7
  • 19
  • Have you tried loading jquery, kendo and knockout via normal script tags and not deal with them in your AMD modules at all? – RainerAtSpirit Mar 07 '14 at 21:50
  • No, I haven't. I will, now, even though this a work around I'm not really super happy with :) – aup Mar 07 '14 at 22:14
  • For large frameworks like kendo that have their own set of dependencies e.g. jquery version, I tend not to bundle them with my own AMD modules. Personal preference, I know. Take a look at – RainerAtSpirit Mar 08 '14 at 10:44

1 Answers1

3

For large frameworks like kendo that have their own set of dependencies e.g. jquery version, I tend not to bundle them with my own AMD modules. Personal preference, I know. Take a look at how you could load jquery , knockout and kendo via normal script tags in the .NET example

 <body>
        <div id="applicationHost"></div>

        <script type="text/javascript" src="~/Scripts/jquery-1.9.1.js"></script>

        <script type="text/javascript" src="~/Scripts/whateverKendoVersionGoesHere.js"></script>

        <script type="text/javascript" src="~/Scripts/knockout-2.3.0.js"></script>
        <script type="text/javascript" src="~/Scripts/bootstrap.js"></script>

        <script type="text/javascript" src="~/Scripts/require.js" data-main="/App/main"></script>
    </body>

That way jquery and knockout will be loaded as globals. In main.js you'd have to define jquery and knockout in order to make them available to Durandal (see main.js) as Durandal internally is still using them as AMD modules.

requirejs.config({
    paths: {
        'text': '../Scripts/text',
        'durandal': '../Scripts/durandal',
        'plugins': '../Scripts/durandal/plugins',
        'transitions': '../Scripts/durandal/transitions'
    }
});

define('jquery', function () { return jQuery; });
define('knockout', ko);

define(['durandal/system', 'durandal/app', 'durandal/viewLocator'],  function (system, app, viewLocator) {
   ...
});
RainerAtSpirit
  • 3,723
  • 1
  • 17
  • 18
  • Thanks! I'm trying this now. I'm wondering though, how do I set up shims for scripts depending on jquery when I don't define a path to jquery in the require.config-section? Also, how should I set up the `define('jquery', function() { return jQuery; });` in the weyland config for optimization? – aup Mar 10 '14 at 06:49
  • Try without any configuration first and if weyland/rjs complains set jquery and knockout to 'empty'. – RainerAtSpirit Mar 10 '14 at 07:58
  • I just got it working.. Don't know exactly what did it in the end but I'm now referencing to the kendoui-script in my custom binding directly and I have added jQuery-and knockout-script tags in index.html like you proposed. Thanks! Now I'm facing something else extremely strange, which I haven't experienced before. Some of my bindings, which worked before moving jquery and knockout to script tags in index, are not working anymore. The "foreach" binding is for example not working in some places, but not errors are thrown from main-built :/ – aup Mar 10 '14 at 08:27
  • That's odd. Try to reproduce a small sample. You could use a fork of https://github.com/dFiddle/dFiddle-2.0 as starting point. – RainerAtSpirit Mar 10 '14 at 13:13
  • 1
    I updated my knockout to 3.1.0 (was running 2.3.0 before) and removed the global definition of knockout from index.html. I also removed the jQuery-path from requirejs.config in main.js to only use the global one referenced via a normal script tag in index.html.This seems to have solved my binding related issues. – aup Mar 10 '14 at 14:04