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

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.

Related

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.

router not found error in ui-router angularjs with requirejs

I have included ui-router.js for angularjs . But somehow i am not getting it to work with requirejs.
require.config
baseUrl:"/Scripts/app"
paths :
jquery : "libs/jquery/jquery-2.0.3"
bootstrap : "libs/bootstrap/bootstrap"
angular : "libs/angular/angular"
domReady : "libs/requirejs/domReady"
blockui : "libs/jquery.blockUI"
"ui-router" : "libs/angular/angular-ui-router"
"angular-resource" : "libs/angular/angular-resource"
shim:
jquery:
exports:
"jquery"
bootstrap:
depts:["jquery"]
angular:
exports:
"angular"
"ui-router":
exports:
"ui.router"
deps : ['angular']
blockui :
deps : ["jquery"]
"angular-resource":
deps: ['angular']
deps :['app','utils/common']
require ['angular','jquery','bootstrap','routes'] ,(angular,$) ->
$(document).ready ->
angular.bootstrap document,['app']
now my app.coffee is
define ['angular','angular-resource','ui-router'] , (angular) ->
angular.module 'app',['ngResource']
the console gives error in chrome
Uncaught TypeError: Cannot read property 'router' of undefined
and
TypeError: g is undefined
g = g[part];
in firefox . Why am I not able to use ui-router as my module to load it into my modules for route.coffee ?
finally got the answer from this guy in ui-router project here is the answer link
Ui-Router Issue for requirejs load with AMD
"ui-router":
exports:
"ui.router"
deps : ['angular']
especially "ui.router" is the bad guy here.
solution: don't use the dot in its name.
i used "uiRouter" even for the export!
if the module name is incorrect, requirejs can't load the script file. so your can't get the router.
in development environment, you should open the console window, in this window, you should find the error from requirejs.

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

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"] }
}
});

Requirejs2: How to handle own files?

I have configured requirejs to load the core libs (jquery, underscore, backbone).
Now I would like to add my backbone models, controllers, views, etc to be loaded asyncronly
I found a lots of tutorials to this topic and lots of "ready" boilerplates unfortunatly I mentioned that most approaches are depreceated or rather complicated (even there are better approaches).
One example is how I configured requirejs for the main libs:
https://stackoverflow.com/a/10914666/1309847
So how do I load Backbone Views, Models, Collections, Routers, Controllers and Templates with a simple and valid Requirejs configuration?
I followed youre advice but get some strange error
main.js
require.config({
paths: {
jquery: 'vendors/jquery/jquery',
underscore: 'vendors/underscore/underscore',
backbone: 'vendors/backbone/backbone'
},
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
require(['app'], function(app){
});
app.js
define(['jquery', 'underscore', 'backbone'], function($, _, Backbone){
var Message = new Backbone.Model.extend({
//idAttribute: '_id',
//defaults: { body: '' }
//url: function(){ return this.id ? '/messages/' + this.id : '/messages'; }
});
var newMessage = new Message({ body: 'hi' });
newMessage.save();
});
The error occours in app.js:
Uncaught TypeError: Object [object Object] has no method 'apply'
When I comment the new Backbone.Model.extend part I don't get any error anymore.
in my experience, the best way to bootstrap your application is by creating a Backbone.Router. So you can associate urls with your application functionality.
If you are using RequireJS+Backbone, you probably have a main.js where RequireJS is configured (paths, shims, etc). The first call to "require" is used to load a initial script in order to bootstrap the whole app.
For example:
/**
* main.js - RequireJS bootstrap
*/
require.config({
paths: {
//your paths
},
shim: {
//your shims
}
});
require(
[
'app' //app.js is at the same directory as main.js
],
function(app) {
app.init();
}
);
then in app.js you can create a new Router instance, or you can just start creating Views and Models.
For further reference: http://addyosmani.github.com/backbone-fundamentals/
So as I have now understood right: You have to wrap a requirejs function around youre own custom js file.
The function is called define. The first parameter is an array of the dependencies which you have defined in the main.js file or a relative path to another custom js from you.
The second parameter is the callback which holds the original file. Important is that you return the object, function, array or variable which you want to share.
The whole thing looks like this:
define(
['underscore', 'backbone'], // the dependencies (either relative paths or shortcuts defined in main.js
function(_, Backbone){ // the return statement of the deps mapped to a var
var MessageModel = Backbone.Model.extend({ // the original code, file
defaults: { body: '' },
initialize: function(){}
});
return MessageModel; // the return statement, sharing the "final result", sometimes you return the initialize parameter
});
The same for a collection wrapping the models:
define(
['jquery', 'underscore', 'backbone', 'models/message_model'], // deps and the last one is the relative path
function($, _, Backbone,MessageModel){ // same as above explained
var MessageCollection = Backbone.Collection.extend({
model: MessageModel,
initialize: function(){}
});
return MessageCollection;
});
I now only have to figure out how I can bootstrap to whole application. But I think I need more knowledge of backbone to do this :)

Resources