backbone.marionette with handlebars throwing exceptions trying to load my template - backbone.js

here is the error thrown to my console
Uncaught TypeError: Object has no method 'chain' hbs.js:282
getExternalDeps hbs.js:282
(anonymous function) hbs.js:306
xhr.onreadystatechange hbs.js:73
Uncaught Error: Load timeout for modules: hbs!templates/reset_unnormalized2,hbs!templates/pages/login_unnormalized3,hbs!templates/reset,hbs!templates/pages/login
http://requirejs.org/docs/errors.html#timeout require.js:160
i'm using the handlebars-require-plugin and i've even tried adding "hbs" to my require shim but the result is the same.
here is my marionette view code:
define([
"bootstrap", // bootstrap does not export anything, so no arg sent to our function
"marionette",
"session", "events",
"hbs!templates/pages/login"
], function( Marionette, Session, Events, LoginTemplate ){
return Marionette.View.extend({
template : {
type : "handlebars",
template : LoginTemplate
}
});
});
i have no idea what's going on here and every search i've pulled up has yielded no useful results.
what's happening? why is this happening? please help.

Could be that you have your args to your callback incorrectly defined? If a value does not define anything (such as bootstrap) then make it last. Right now your Marionette arg contains the undefined value of bootstrap, Session now holds Marionette etc.
define([
"marionette",
"session", "events",
"hbs!templates/pages/login",
"bootstrap", // bootstrap does not export anything, so no arg sent to our function
], function( Marionette, Session, Events, LoginTemplate ){
return Marionette.View.extend({
template : {
type : "handlebars",
template : LoginTemplate
}
});
});

i figured it out.
it turns out my problem was not related to the hbs plugin as it was with using it, handlebars, and json2 with requirejs.
the first problem, as described above, was solved by switching out the lodash library with underscore. i was under the impression that these two were interchangeable, but apparently that is NOT the case.
then i was getting errors that "stringify" is not a function on the object null which led me to find that JSON was not defined inside hbs.
i had to go back to my require.config({ shim:{} }) and define json2 with an export of JSON
now i am not getting errors from hbs but i have to figure out why my view is not displaying.
here is my config code, should anyone else be interested.
require.config({
// paths to required javascript files
paths : {
bootstrap : "../assets/js/bootstrap.min",
jquery : "../assets/js/jquery.min",
json2 : "../assets/js/json2",
underscore : "../assets/js/underscore.min",
backbone : "../assets/js/backbone.min",
marionette : "../assets/js/backbone.marionette.min",
hbs : "../assets/js/hbs",
handlebars : "../assets/js/handlebars",
i18nprecompile : "../assets/js/hbs/i18nprecompile"
},
// "shim" will allows us to load in deps synchronously so that we do not
// run into a situation where dependencies are not available
shim : {
json2 : { exports : "JSON" },
jquery : { exports : "jQuery" },
underscore : { exports : "_" },
backbone : {
deps : ["jquery", "underscore", "json2"],
exports : "Backbone"
},
marionette : {
deps : ["jquery", "underscore", "json2", "backbone"],
exports : "Marionette"
},
hbs : {
deps : ["jquery", "underscore", "json2", "i18nprecompile", "handlebars"],
exports : "hbs"
},
bootstrap : { deps : ["jquery"] }
}
});

Related

backbone.js: Right-hand side of 'instanceof' is not an object

I'm newer with jquery and backbone, hope someone could help me with this error. I have a web application that, sometimes, throws this error in the console
require.js:900 TypeError: Right-hand side of 'instanceof' is not an object
at child.setElement (backbone.js?__nc__=1527837925799:1040)
at child._ensureElement (backbone.js?__nc__=1527837925799:1102)
at child.Backbone.View (backbone.js?__nc__=1527837925799:990)
at child [as constructor] (backbone.js?__nc__=1527837925799:1545)
at new child (backbone.js?__nc__=1527837925799:1545)
at child.initialize (application.js?__nc__=1527837925799:357)
at child.Inditex.Application (backbone-inditex-1.2.0.js?__nc__=1527837925799:27)
at new child (backbone.js?__nc__=1527837925799:1545)
at createApp (main.js:201)
at Object.execCb (require.js:1690)
If this error happens, with a reload of the webpage is fixed (sometimes with 3 or 4 times) but I can't know why this happens.
I have found the line where this error is thrown. In backbone.js file, the method setElement
setElement: function(element, delegate) {
debugger;
if (this.$el) this.undelegateEvents();
this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
this.el = this.$el[0];
if (delegate !== false) this.delegateEvents();
return this;
},
sometimes, Backbone.$ is not an object and is when the error hapens.
¿Any idea for resolving this error? I'm using backbone.js 1.1.0
Thanks in advance
In my case, I could fix it change my main.js. The error was that, in some cases backbone was loaded before jquery were loaded. My main.js was like this
shim : {
'underscore' : {
exports: '_'
},
'backbone' : {
deps : ['underscore'],
exports: 'Backbone'
}
I had to add a deps in backbone for jquery, like this
shim : {
'underscore' : {
exports: '_'
},
'backbone' : {
deps : ['jquery','underscore'],
exports: 'Backbone'
}
The main reason of this problem is backbone.js loaded before jQuery, so what you need to do is just make sure that jQuery loads before backbone.js.

BackboneJS How to include MomentJS <locale> feature

I want to include the locale-feature from MomentJS into one of my Backbone Views. http://momentjs.com/docs/#/i18n/adding-locale/ - but I get an error:
Uncaught TypeError: undefined is not a function - and it refers to:
return moment.defineLocale('da', {
In my config.js I have:
require.config({
deps: ['main'],
paths: {
jquery : '../lib/jquery-2.1.1.min',
underscore : '../lib/lodash-2.4.1',
backbone : '../lib/backbone',
moment : '../lib/moment.min',
locale : '../lib/locale/da'
},
And in my View I have:
define([
'app',
'backbone',
'moment',
'locale'
],
function (App, Backbone, moment, locale) {
...
Does anyone know what the issue could be?
Here is the oficial documentation http://momentjs.com/docs/#/use-it/require-js/
seems to me that there is a little trick to work with requirejs

Properly loading webshims / modernizr with requirejs?

I have modernizr / pollyfiller included at the top of my index.html file, and in my main.js:
require.config({
paths : {
'jquery' : 'lib/jquery-1.10.2.min',
'jqdate' : 'lib/jquery.dateFormat-1.0',
'webshims' : 'lib/polyfiller'
},
shim : {
'lib/underscore' : {
exports : '_'
},
'lib/backbone' : {
deps : ["lib/underscore", "jquery"],
exports : 'Backbone'
},
"modernizr" : {
deps : ["jquery"],
exports : "modernizr"
},
"webshims" : {
deps : [ "jquery", "lib/modernizr-custom"],
exports: "webshims"
}
}
});
var router, vent;
require(["jquery", "lib/underscore", "lib/backbone", "app", "lib/modernizr-custom", "webshims"], function($, _, Backbone, Router, modernizr, webshims) {
$(function() {
$.webshims.setOptions('forms forms-ext', {
replaceUI : false,
waitReady : false
});
$.webshims.polyfill('forms forms-ext');
router = new Router();
vent = _.extend({}, Backbone.Events);
$.expr.cacheLength = 1;
Backbone.history.start({
});
});
});
This will generally load fine, however, sometimes it looks like webshims is not defined by the time I try to call:
$.webshims.setOptions('forms forms-ext', {
replaceUI : false,
waitReady : false
});
$.webshims.polyfill('forms forms-ext');
and I get the error: TypeError: $.webshims is undefined
Is there a better way to load this?
edit
So, I updated the script like you said, and had to capitalize Webshims in the paths and shim definition. It loads fine but now I get an error:
Uncaught SyntaxError: Unexpected token <
in Chrome and
SyntaxError: syntax error
<!DOCTYPE html>
in firefox
Updated Answer
Alexander Farkas pointed out in a comment that polyfiller defines itself as "polyfiller" like this:
define('polyfiller', ['jquery'], factory);
So:
No shim should be required to load polyfiller.js.
The module defined by polyfiller.js should always be referred to as "polyfiller". So there has to be a paths setting that maps the module name polyfiller to the actual path of the polyfiller.js file.
So the original config should be modified to remove the "webshims" shim, then the paths setting "webshims": "lib/polyfiller" should become "polyfiller": "lib/polyfiller" and the require call should be:
require(["jquery", "lib/underscore", "lib/backbone", "app", "lib/modernizr-custom", "polyfiller"], function($, _, Backbone, Router, modernizr) {
I've dropped the last variable from the function's parameters because there's no need to pass the module value since the polyfiller.js file registers itself as $.webshims.
This is similar to how jQuery defines itself as "jquery" (it needs no shim and is always called "jquery").
Original Answer
Change your require call so that you require "webshims" instead of "lib/polyfiller":
require(["jquery", "lib/underscore", "lib/backbone", "app", "lib/modernizr-custom", "webshims"], ...
The code in your question shows you've set the paths configuration option so that the module name "webshims" resolves to "lib/polyfiller", and created what looks like a sensible shim for it. However, when you require the webshims module you refer to it as "lib/polyfiller". RequireJS does not do a reverse resolution to figure out that "lib/polyfiller" is "webshims".
Alternatively, you could drop the "webshims" name from paths and rename the shim so that it is set for "lib/polyfiller". However, I consider it to be a better practice to refer to 3rd party libraries by one-word names throughout an application rather than have paths for them. So "jquery", "bootstrap", "underscore", and "webshims" etc. rather than "lib/...".

require js + backbone + marionette: Cannot read property 'Marionette' of undefined

I just started off learning backbone and want to manage my dependencies using require js.
My code is as follows:
main.js:
//Require.js
require.config({
paths : {
jQuery : '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min',
jQueryUI : '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min',
lodash : 'libs/lodash/lodash',
backbone : 'libs/backbone/backbone',
marionette : 'libs/marionette/marionette'
},
shim : {
backbone: {
deps : ['jQuery', 'lodash'],
exports : 'backbone'
},
marionette: {
deps : ['backbone'],
exports : 'marionette'
}
}
});
require(['initialize'], function(initializer){
alert("initialized");
});
initialize.js:
define(['backbone', 'marionette'], function(Backbone, Marionette){
var appZwoop = new Backbone.Marionette.Application();
var options = {
};
//Initialize functions
appZwoop.addInitializer(function(options){
});
//Application events
appZwoop.on("initialize:before", function(options){
});
appZwoop.on("initialize:after", function(options){
});
//Start the application
appZwoop.start(options);
appZwoop.addRegions({
mainRegion : "#mainRegion",
headerRegion: "#headerRegion"
});
return appZwoop;
}
The browser console throws me the error:
Uncaught TypeError: Cannot read property 'Marionette' of undefined
What am I doing wrong ... ?
Change you Backbone shim to capitalize Backbone in the exports:
backbone: {
deps : ['jQuery', 'lodash'],
exports : 'Backbone'
},
because Backbone defines itself as Backbone and not backbone. There may be a problem elsewhere but you definitely have to do this.

How can I use Marionette in my typescript project with require.js

I'm having some error as below;
Uncaught ReferenceError: Marionette is not defined
I am using the following files(main.ts->config, app.ts-> first class of the app) with using the grunt watch (typescript compile with --module amd). My question is refer to my error problem, How can I import Marionette (modules/marionette.d.ts) so that I could use Marionette.Application(); and configure my application?
main.ts;
// Require JS all the things
/// <reference path="modules/require.d.ts" />
/// <reference path="modules/marionette.d.ts" />
require.config({
basePath: 'assets/js',
paths : {
backbone : 'vendor/backbone',
underscore : 'vendor/underscore',
jquery : 'vendor/jquery',
marionette : 'vendor/backbone.marionette',
debug : 'vendor/ba-debug',
handlebars: 'vendor/handlebars'
},
shim : {
jquery : {
exports : 'jQuery'
},
underscore : {
exports : '_'
},
backbone : {
deps : ['jquery', 'underscore'],
exports : 'Backbone'
},
marionette : {
deps : ['jquery', 'underscore', 'backbone'],
exports : 'Marionette'
},
handlebars: {
exports:'Handlebars'
},
debug: {
exports: 'debug'
}
}
});
// initalise the app
// load AMD module app.ts (compiled to app.js) , tsc --module AMD main.ts
// and include shims $, _, Backbone
require(['backbone', 'app','routers/router','routers/controller', 'debug', 'jquery','underscore'], (Backbone, App, CustomRouter, AppController, debug, $, _ ) => {
debug.log('starting app');
App.on('initialize:after', function(options) {
if (Backbone.history) {
Backbone.history.start();
}
});
var router = new CustomRouter({
controller : new AppController()
});
App.start();
});
app.ts;
/// <reference path="modules/marionette.d.ts" />
var app:any = new Marionette.Application();
app.addRegions({
header : '#Header',
// main : CustomRegion.extend({el: '#main'})
main : '#Main'
});
app.addInitializer(function() {
});
Thanks
You need to tell requireJS to load marionette before it starts running app.js.
This is done using amd-dependency:
/// <amd-dependency path="marionette"/>
You can see a sample here : https://github.com/basarat/typescript-amd/blob/master/app/scripts/app.ts
Along with the video tutorial: http://www.youtube.com/watch?v=4AGQpv0MKsA
I'm using this as a reference and it works perfectly Structuring Backbone with RequireJS and Marionette . Hope this help you to solve your issue! :)

Resources