ONYX ONYX - 19 days ago 19
Javascript Question

Module name has not been loaded yet for context using RequireJS text plugin

I'm using text.js to load templates and I'm getting an error on

require('text!templates/categories.html')


the error is

Uncaught Error: Module name "text!templates/categories.html_unnormalized2" has not been loaded yet for context:


Have a look at my view section in the require loading process of the template that's where the error is thrown.

Project directory structure:

js
/app
....
views/categories
templates/categories
/lib
/jquery
/underscore
/backbone
/text
/vendor
/jquery-ui
/fancytree


RequireJS configs:

require.config({
// The shim config allows us to configure dependencies for
// scripts that do not call define() to register a module

shim: {

underscore: {
exports: '_'
},
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
'jquery-ui': {
exports: "$",
deps: ['jquery']
},
'fancytree': {
deps: ['jquery-ui']
},

},
paths: {
'jquery': '../lib/jquery/jquery',
'underscore': '../lib/underscore/underscore',
'backbone': '../lib/backbone/backbone',
'text': '../lib/text/text',
'jquery-ui': '../vendor/jquery-ui/jquery-ui',
'fancytree': [
'../vendor/fancytree/fancytree',
'../vendor/fancytree/fancytree.table'
],
},

baseUrl: '/js/app',

});


view:

define(['jquery-ui', 'fancytree', 'require'], function(ui, fancytree, require){

'use strict';

var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
tpl = require('text!templates/categories.html') /* this line here produces error loading text.js*/,
template = _.template(tpl);


return Backbone.View.extend({
el: $('#tree'),
initialize: function() {

this.listenTo( this.collection, 'reset add change remove', this.render, this );
this.collection.fetch();
},
initFancyTree: function() {
console.log('tree');
$('#fancytree').fancytree();

},
render: function() {

console.log(this.collection.toJSON())
this.$el.html(template());
//this.initFancyTree();
return this;
}
});
})

Answer

You're trying to require modules using CommonJS syntax which RequireJS tries to emulate by loading the template asynchronously.

Since it's not ready yet when you try to use it, it throws the error.

You'd only need the following to get it to work:

define([
    'jquery', 'underscore', 'backbone', 'jquery-ui', 'fancytree',
    'text!templates/categories.html'
], function(
    $, _, Backbone, ui, fancytree, 
    tpl
) {
    'use strict';
    return Backbone.View.extend({
        el: $('#tree'),
        template: _.template(tpl), // can be put here directly
        initialize: function() {
            // only has 3 parameters
            this.listenTo(this.collection, 'reset add change remove', this.render);
            this.collection.fetch();
        },
        render: function() {
            this.$el.html(this.template());
            return this;
        }
    });

});

Additional information (and similar questions):