Backbone ReferenceError - backbone.js

I have Backbone view that looks like this:
App.Views.HistoricalDataSelector = Backbone.View.extend({
initialize: function (options) {
this.template = JST['backbone/templates/historical_data_selector'];
this.collection = options.collection;
this.model = options.model;
this.render();
},
myCollection: function() {
return this.collection.byReportType(this.model.get('report_type')).byReportOrganizationType(this.model.get('report_organization_type'))
},
render: function () {
this.$el.html(this.template({
collection: myCollection,
model: this.model
}));
}
});
when I try to render it Backbone returns me the following error:
ReferenceError: myCollection is not defined
But when I change render method to this:
render: function () {
this.$el.html(this.template({
collection: this.collection.byReportType(this.model.get('report_type')).byReportOrganizationType(this.model.get('report_organization_type')),
model: this.model
}));
}
why he can't find this myCollection method?

You forgot the this keyword, and probably also to invoke the method:
render: function () {
this.$el.html(this.template({
collection: this.myCollection(),
//-----------^ view reference ^---- function invocation ------
model: this.model
}));
}

Related

View.stopListening() not working

http://jsfiddle.net/sbel/3KAhC/
In this fiddle code the even though the stopListening method is called the on method is still in effect as can be seen by the output. What am I doing wrong?
JavaScript:
// Define View
var SomeView = Backbone.View.extend({
initialize: function () {
// Listen to the model
this.model.on('change', this.render, this);
},
render: function () {
$("#message").append("<br>render called");
},
close: function () {
this.stopListening();
}
});
var SomeModel = Backbone.Model.extend({});
var someModel = new SomeModel({
name: 'Foo'
});
var someView = new SomeView({
model: someModel
});
someModel.set('name', 'Bar');
someView.close();
someView = null;
someModel.set('name', 'Zoo');
Use this.listenTo(this.model, 'change', this.render) instead of this.model.on('change', this.render, this):
listenTo object.listenTo(other, event, callback)
Tell an object to
listen to a particular event on an other object. The advantage of
using this form, instead of other.on(event, callback), is that
listenTo allows the object to keep track of the events, and they can
be removed all at once later on.
And an updated Fiddle http://jsfiddle.net/nikoshr/3KAhC/1/

backbone.js iterate a collection

I have set up a collection for Logs. The api returns the results as JSON. I saw a previous topic where it was suggested to add the parse method on the collection. Having done so, when I execute the code I am not getting any output to the console. Nevertheless, I am new to Backbone so any insight and/or guidance would be appreciated. My understanding of collection.each may not be correct.
var Log = Backbone.Model.extend({});
var LogList = Backbone.Collection.extend({
model: Log,
url: 'api/logs',
parse: function(response) {
return response.logs;
}
});
var LogListView = Backbone.View.extend({
el: $('#logs-list'),
initialize: function() {
this.collection = new LogList();
this.collection.fetch();
this.render();
},
render: function() {
this.collection.each(function(log) {
console.log('log item.', log);
});
}
});
$(document).ready(function(){
console.log('ready.');
new LogListView();
});
Fetch is asynchronous. Rewrite your code to call render with a callback:
var LogListView = Backbone.View.extend({
el: $('#logs-list'),
initialize: function() {
var self = this;
this.collection = new LogList();
this.collection.fetch().done(function(){
self.render();
});
},
render: function() {
this.collection.each(function(log) {
console.log('log item.', log);
});
}
});

Backbone - Collection fetch returns undefined?

I have an application using backbone but whenever I call the fetch() method for the collection it returns undefined:
// App
(function () {
window.app = {};
app.collections = {};
app.models = {};
app.views = {};
$(function () {
app.collections.complaintTypes = new app.collections.ComplaintTypesCollection();
app.views.complaintTypesView = new app.views.ComplaintTypesView({ collection: app.collections.complaintTypes });
});
})();
// Collections
(function (collections, model) {
collections.ComplaintTypesCollection = Backbone.Collection.extend({
initialize: function () {
this.fetch();
},
model: model,
url: '/api/ComplaintTypes'
});
})(app.collections, app.models.ComplaintType);
// Models
(function (models) {
models.ComplaintType = Backbone.Model.extend({
idAttribute: 'ComplaintTypeId'
});
})(app.models);
// Views
(function (views) {
views.ComplaintTypesView = Backbone.View.extend({
initialize: function () {
this.collection.on('reset', this.render, this);
},
render: function () {
console.log(this.collection);
}
});
})(app.views);
But this doesn't return anything? If I use fiddler and go to my URL: /api/ComplaintTypes I do retrieve data back so I'm not sure what Im doing wrong here?
Deleting "model" line in the collection file worked for me.
Fetch is async. If you need to get the results, you need to pass a "success" handler, i.e.:
function myHandler(models) {
}
...
this.fetch({success: myHandler});
I think the problem is that you create the view while the collection has not been fetched yet (because of JS's asynchronous behavior). Try this way:
$(function () {
app.collections.complaintTypes = new app.collections.ComplaintTypesCollection();
app.collections.complaintTypes.fetch({success:function(){
app.views.complaintTypesView = new app.views.ComplaintTypesView({ collection: app.collections.complaintTypes });
}});
});
And remove the initialize function from your collection.

Backbone: how can I reference a Collection from a Model

I know it's more often done in the opposite way, but in my specific use case I'd need to have a Model PostsTimes with a reference to a Collection (of another Model Post). Right now I'm trying:
var Posts = Backbone.Collection.extend({
model: Post
});
var posts = new Posts(); // my collection
var PostsTimes = Backbone.Model.extend({
url: "api/times.php",
initialize: function(options){
this.posts = options.posts;
},
test: function(){
console.log(this.posts);
}
});
var poststimes = new PostsTimes({posts: posts});
But this.posts in PostsTimes always stays undefined. Is there any way I can do this without defining a global variable?
The structure of what you have is correct, so the reason it would be logging undefined is because the this in your test function is something other than the model's instance.
So your PostsTimes would become
var PostsTimes = Backbone.Model.extend({
url: "api/times.php",
initialize: function(options){
_.bindAll(this);
this.posts = options.posts;
},
test: function(){
console.log(this.posts);
}
});
var PostsTimes = Backbone.Model.extend({
url: "api/times.php",
initialize: function(options){
_.bindAll(this, 'test');
this.posts = options.posts;
},
test: function(){
console.log(this.posts);
}
});

Backbone Collection Not Fetching w/ ServiceStack

Alright, so here is my main backbone code
(function ($) {
var Job = Backbone.Model.extend({});
var JobList = Backbone.Collection.extend({
model: Job,
url: "/api/jobs?format=json"
});
var JobView = Backbone.View.extend({
el: $('#jobs'),
_templatesrc: $("#job-template").html(),
_template: {},
initialize: function () {
var self = this;
_.bindAll(this, 'render');
//create the template
this._template = Handlebars.compile(this._templatesrc);
//setup data
this.collection = new JobList();
//response function from server query
var response = function () {
console.log(arguments);
self.render();
};
var response2 = function () {
console.error(arguments);
self.render();
};
this.collection.fetch();
},
render: function () {
console.log("models", this.collection.models);
$(this.el).html(this._template(this.collection.models));
}
});
var view = new JobView();
})(jQuery);
When i do this.collection.fetch() i get nothing. When i do this.collection.fetch({ success:response, error:response2}); the following error is thrown:
Backbone.View.extend.initialize.response2 app.js:29
g.wrapError backbone-min.js:104
f.Callbacks.o jquery.min.js:2
f.Callbacks.p.fireWith jquery.min.js:2
w jquery.min.js:4
f.support.ajax.f.ajaxTransport.send.d
In chrome i can tell that it returns a JSON response though, which looks like
[{"Client":"hi",
"ReporterTime":"\/Date(-62135578800000-0500)\/",
"TimeTaken":PT0S,
"Status":"Start"}]
Any ideas on why Backbone isn't turning my JSON response into the collection?
Unless I'm mistaken PT0S is not valid JSON. Try to return it wrapped in quotes:
[{"Client":"hi",
"ReporterTime":"\/Date(-62135578800000-0500)\/",
"TimeTaken":"PT0S",
"Status":"Start"}]
I've just fixed support for TimeSpans in ServiceStack.Text's JsonSerializer.
Will be available from v3.94+ on NuGet or GitHub.

Resources