Backbone-Debugger
Backbone-Debugger copied to clipboard
Debugger "Waiting for Backbone..." indefinitely
Hi all,
The debugger doesn't seem to start properly on a backbone site I work on. I've found an error occurring in the console when inspecting the debugger itself, but before I spend hours trying to figure out what's wrong I figured I'd post it here unless someone else has solved a similar issue before.
The site I'm trying to debug a search site for airport hotels and parking, an example product search is: https://v2.holidayextras.co.uk/?agent=WEB1&ppcmsg=#carpark?arrive=&customer_ref=&depart=LGW&flight=TBC&in=2015-03-08&out=2015-03-01&park_from=07%3A00&park_to=07%3A00&term=&terminal=
It's very backbone heavy, but doesn't seem to big that it should cause the debugger to break - I've had it working before intermittently.
The error I'm getting when loading the debugger is:
This issue manifests itself as the debugger "Waiting for Backbone..." indefinitely. If there's a simple fix I might be able to get a pull request worked up this week during work hours, otherwise it'll have to be something I do in my own time.
I'm not getting your extension server error and exception, but they seem related with trying to evaluate code on a page frame with a given url, this is done the first time on inspector start to check if the backboneAgent has already been injected: https://github.com/Maluen/Backbone-Debugger/blob/master/js/panel/backboneAgentClient.js#L50
The page could contain some "unusual" frame for which no main execution context can be found, as you can see on https://code.google.com/p/sandrop/source/browse/projects/SandroProxyWeb/chrome_devtools_src/inspector_chrome_build/ExtensionServer.js?name=1_5_96_external_intents#917
Moreover, Backbone is stored as a global object (window.Backbone) and the backboneAgent detected it, as you can see by evaluating "window.__backboneAgent.isBackboneDetected" on the console. It also detected components, as you can see by evaluating for example "window.__backboneAgent.appComponentsInfos['View']"
Is a problem of communication with the panel, checking..
Basically was a problem with calculating the url of a frame:
chrome devtools uses the original frame url WITHOUT an eventual hash string, while the content script was using the full href, hence they were not able to communicate.
Let me know if you encounter any other issue
Note: remember to reload the extension by clicking on the "Reload" button from chrome://extensions/ since the change was to the content script.
That commit fixes the issue completely, fantastic, thanks @Maluen.
I still have this problem...updated to 0.3.0. I do get my views from "window.__backboneAgent.appComponentsInfos['View']" but the chrome dev-tool do not show them, it only says "Waiting for inspected page loading..."
@burmester is it possible for you to include some code to reproduce the issue or just post a link to the application?
There might be some other edge case with the frame url calculation.
This is a very minimized code, but i still gets the error?
Anything else you might need?
init.js
define(function(require) {
"use strict";
var _ = require('underscore'),
Backbone = require('backbone'),
template = require('tpl!apps/assignments/templates/teacherMentorAdminAssignments'),
Assignments = Backbone.View.extend({
initialize: function(options) {
this.assignments = options.assignments;
},
render: function() {
this.$el.html(template({assignments: this.assignments.toJSON()}));
return this;
}
}),
AssignmentCollection = Backbone.Collection.extend({
model: Backbone.Model.extend({
defaults: {
"title": "",
"type": "Inlämning",
"description": "",
"deadline": ""
}
}),
initialize: function(collection, options) {
},
fetch: function(options) {
return $.Deferred().resolve().promise();
},
}),
data = [{
"id": 122350,
"created": "2015-05-18",
"title": "atte",
"description": "",
"type": "Inlämning",
"tags": [{"id": 303257340, "title": "Engelska", "abbreviation": "En", "type": "curriculum"}, {
"id": 303257749,
"title": "Matematik",
"abbreviation": "Ma",
"type": "curriculum"
}],
"owner": {"id": 27759, "name": "Emma Emmasson"},
"assignedTo": [27759]
}, {
"id": 122359,
"created": "2015-05-18",
"title": "shoow!",
"description": "",
"type": "Inlämning",
"tags": [{"id": 303257213, "title": "Bild", "abbreviation": "Bl", "type": "curriculum"}, {
"id": 303257749,
"title": "Matematik",
"abbreviation": "Ma",
"type": "curriculum"
}],
"owner": {"id": 27759, "name": "Emma Emmasson"},
"assignedTo": [27759]
}, {
"id": 122368,
"created": "2015-05-18",
"title": "asdf",
"description": "",
"type": "Inlämning",
"tags": [{"id": 303260502, "title": "Teknik", "abbreviation": "Te", "type": "curriculum"}],
"owner": {"id": 27759, "name": "Emma Emmasson"},
"assignedTo": [27759]
}];
$(document).ready(function() {
var assignmentsCollection = new AssignmentCollection(data),
assignmentsView = new Assignments({
assignments: assignmentsCollection,
el: $('#uppgifter #app')
});
new (Backbone.Router.extend({
routes: {
"(/)": "assignments",
"assignments": 'assignments',
},
assignments: function() {
var assignmentsPromise = assignmentsView.assignments.fetch({remove: false}),
self = this;
$.when(assignmentsPromise).then(function() {
assignmentsView.render();
});
}
}))();
Backbone.history.start();
});
});
template.tpl
<ul class="uk-item-list">
{[ _.each(assignments, function(assignment, i) { ]}
<li class="uk-item">
<button class="btn btn-danger pull-right deleteMe" data-id="{{assignment.id}}">Ta bort</button>
<a href="#answers/{{assignment.id}}">
<span class="title">{{ assignment.title }}</span>
</a>
</li>
{[ }); ]}
</ul>
@burmester I loaded and served your code on localhost. With current master version and with 0.3.0 snapshot components are displayed:
Thus probably the problem here is with the URL used to access the application. Can you provide an example of the URL structure you're using? Eg host, path, hash, parameters and so on.
http://localhost:8080/unikum/uppgifter/uppgifter.html?__pid=27751 and when you go down a bit in the the app: http://localhost:8080/unikum/uppgifter/uppgifter.html?__pid=27751#answers/122430/27756
We other Backbone apps and they work fine in the debugger: https://skolbanken.unikum.net/unikum/skolbanken
To bad this is part is under development and secure behind passwords..
Sorry for all the Swedish language ;)
I have even tried this, and can't get it to work..
define(function(require) {
var Backbone = require('backbone'),
Assignments = Backbone.View.extend({
render: function() {
$('body').html("<div>hello world</div>");
}
}),
AssignmentCollection = Backbone.Collection.extend({
model: Backbone.Model.extend({
defaults: {
"title": "",
}
}),
}),
data = [{
"title": "atte",
}];
$(document).ready(function() {
var assignmentsCollection = new AssignmentCollection(data),
assignmentsView = new Assignments();
assignmentsView.render();
Backbone.history.start();
});
});
okej! I have found the problem; in our dev-env. we use this code-snippit:
<!--[if !IE]>-->
<link rel="stylesheet/less" media="all" href="<c:url value="/less/unikum.less"/>">
<script>
less = { logLevel: 1 }; // make it shut up
</script>
<script src="<c:url value="${jsPath}/vendor/less.js/dist/less.js"/>"></script>
<!--<![endif]-->
and the parts that breaks it is:
less = { logLevel: 1 }; // make it shut up
@burmester any update on that?
@Maluen I too am seeing "Waiting for Backbone..." indefinitely . We are using a custom built framework called discus with an backbone example app here (discus branch). Would love to be able to use your plugin with it, any suggestions as to how might be able to?
@jonniedarko first requirement is for the Backbone object to be exposed as "window.Backbone", however, if you are uisng webpack, browserify or a similar build system, that's not gonna happen automatically.
If you can't set window.Backbone, then app developers can resort to using https://github.com/Maluen/Backbone-Debugger#backbone-detection, of course, this could be done also by the framework itself after Backbone has been loaded, but would be quite ugly imho.
I also seem to be stuck here.
window.__backboneAgent.isBackboneDetected
returns true
, and window.__backboneAgent.appComponentsInfos['View']
seems to find the models on the page.
Here's my extremely stripped down code that still seems stuck:
window.utils = {
// Asynchronously load templates located in separate .html files
loadTemplate: function(views, callback) {
var deferreds = [];
$.each(views, function(index, view) {
if (window[view]) {
deferreds.push($.get('templates/' + view + '.html', function(data) {
window[view].prototype.template = _.template(data);
}));
} else {
console.log(view + " not found");
}
});
$.when.apply(null, deferreds).done(callback);
},
};
var AppRouter = Backbone.Router.extend({
routes: {
"" : "getServerList",",
},
initialize: function () {
$typesContainer = $('typesContainer');
},
getServerList: function(environment){
if (!environment) {
environment = $("#envDropdown").val();
}
},
});
utils.loadTemplate(['EnvContainerView', 'ServerListView', 'TypeListCollectionView'], function() {
app = new AppRouter();
Backbone.history.start();
});
@SnoringFrog please share the whole code including html files (templates, index.html, etc.)
I cannot share the entire code because some parts of it cannot leave the company. Also, I can't access the project right now as I am on vacation, but as soon as I get back I'll get as much of the code together as I can share and put it here.
@SnoringFrog looks good, the important thing is to have a (minimal) reproducible example.
Okay, this should be everything needed to reproduce the issue.
main.js
var AppRouter = Backbone.Router.extend({
routes: {
"" : "getServerList",
":environment" : "getServerList",
*/},
initialize: function () {
$typesContainer = $('typesContainer');
this.envContainerView = new EnvContainerView();
this.envContainerView.delegateEvents();
$('.envContainer').html(this.envContainerView.el);
},
getServerList: function(environment){
if (!environment) {
environment = $("#envDropdown").val();
}
$serverListElem = $("#getTypesForm .serverList");
$serverListElem.empty();
$serverListElem.html("<p>filler " + environment + "</p>");
},
});
utils.loadTemplate(['EnvContainerView'], function() {
app = new AppRouter();
Backbone.history.start();
});
utils.js
window.utils = {
loadTemplate: function(views, callback) {
var deferreds = [];
$.each(views, function(index, view) {
if (window[view]) {
deferreds.push($.get('templates/' + view + '.html', function(data) {
window[view].prototype.template = _.template(data);
}));
} else {
console.log(view + " not found");
}
});
$.when.apply(null, deferreds).done(callback);
},
};
views/envcontainer.js
window.EnvContainerView = Backbone.View.extend({
initialize: function () {
this.render();
},
events: {
"change #envDropdown" : "loadServerList",
"click #refresh-heartbeats" : "reloadServerList"
},
render: function () {
$(this.el).html(this.template());
return this;
},
loadServerList: function () {
env = this.$('#envDropdown').val();
app.navigate("/"+env, {trigger:true});
},
reloadServerList: function () {
//Should this preserve checkmarks?
Backbone.history.loadUrl(Backbone.history.fragment);
},
});
index.html
<html>
<head>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="centered envContainer">
</div>
<script src="js/libs/jquery/jquery-2.1.4.min.js"></script>
<script src="js/libs/underscore/underscore.min.js"></script>
<script src="js/libs/backbone/backbone.min.js"></script>
<script src="js/libs/bootstrap/bootstrap.min.js"></script>
<script src="js/libs/jquery/datatables.min.js"></script>
<script src="js/utils.js"></script>
<script src="js/views/envcontainer.js"></script>
<script src="js/main.js"></script>
</body>
</html>
templates/EnvContainerView.html
<form name="getTypesForm" id="getTypesForm">
<label for="envDropdown" class="heading">Environment:</label>
<select id="envDropdown" name="envDropdown" autofocus>
<option value="srv2">server1</option>
<option value="srv1">server2</option>
</select>
<span id="refresh-heartbeats">↻</span>
<hr class width="25%">
<div class="serverList"></div>
<br/>
<hr width="25%"/>
</form>
@SnoringFrog since libraries were missing, I've used:
- same jquery version
- latest backbone / underscore version
- disabled bootstrap and jquery datatables
- latest master version of Backbone Debugger
Detection seems to work correctly:
Weird. I don't think I had those versions of those libraries in use, but I intended on updating them anyways (looking at overhauling this app all together), so I'm going to duplicate my project, update those, and strip it down to exactly this to see if it works. I've also just updated to the newest Backbone Debugger in the Chrome Web Store, which says it's version 0.3.1.
If that doesn't work, I'll have to assume it's a browser/OS issue, I guess. Either way, I'll report back when I've done that.
Issue seems to be the same. I only ever get "Waiting for Backbone".
The URLs I'm using to access this page are like this:
file://localhost/Users/username/testdir/backboneapptest/index.html
file://localhost/Users/username/testdir/backboneapptest/index.html#2
@SnoringFrog even from file:// I get it to detect Backbone correctly, even though (obviously) jquery ajax fails from fetching the template file for cross-origin restrictions and no components are detected.
I'm fresh out of ideas then. I guess I'll just have to do without for this app. Oh well, thanks for all the help regardless! Hopefully this issue's something very specific to my setup and doesn't come up like this again lol.