Search code examples
javascriptjqueryasp.netknockout.jsknockout-mapping-plugin

ASP.NET WebForms ko.mapping is undefined


I cannot for the life of me figure out why ko.mapping is undefined.

I'm using the following JS libraries:

  • jquery
  • knockout
  • knockout.mapping
  • moment
  • fullcalendar
  • datatables
  • datatables.columnFilter
  • dataTables.scroller
  • jquery.blockUI

I've tried the following (with hard refreshes after each change):

  1. I've reordered the js files in the head every combination I can. (Thought maybe the on ready function was being called prior to the library loading)
  2. Removed the other JS libraries (thought maybe there was some sort of conflict)
  3. Swapped local file for a cdn reference to knockout-mapping
  4. Created a new file and put knockout and knockout mapping in it and added it to the scripts to include
  5. Changed the file name of the combined file to not include the word mapping(I thought maybe there was something funky about the file name)

Interestingly enough the only two ways I could get this working were

If I copy-pasted the knockout-mapping into the knockout library file(but a new file with a different name but the exact same content did not).

OR

What I actually ended up doing was the following:

$(document).ready(function () {
    .
    .
    .
    var loadKnockoutMapping = function () {
        var s = document.createElement('script');
        s.src = '/cstm/JavaScript/knockout.mapping-2.4.1.js';
        document.body.appendChild(s);

        var callbackTimer = setInterval(function () {
            var mappingIsDefined = false;
            try {
                mappingIsDefined = (ko.mapping !== undefined);
            } catch (e) { }

            if (mappingIsDefined) {
                clearInterval(callbackTimer);
                setupRequestableAssignmentData(); //uses ko.mapping.fromJS function
            }
        }, 100);
    }
    loadKnockoutMapping();
}

Does anyone have any idea what is happening here? I even tried just not adding a new script element to the page and just a timeout function to wait until ko.mapping is not undefined but that didn't work either ko.mapping never ended up being defined to anything.


Solution

  • I think you are "re-inventing" the wheel here. There is a an excellent library for this. http://requirejs.org/

    That will handle the script-loading for you.

    requirejs.config({
        paths: {
            jquery: 'libs/jquery.js',
            knockout: 'libs/knockout.js',
            knockoutMapping: 'libs/knockoutMapping.js'
        }
        shim: {
            'knockout': {
                deps: ['jquery'],
            }
        }
    });
    
    
    require(["jquery","knockout","knockoutMapping",function($,ko,mapping){
        console.log($,ko,mapping);
    });