Backbone : view doesn't update (reset event) - javascript

I'm currently using BackboneJS to get data from my database with a backbone model.
The problem is that my app is not firing my reset event and my data are not displayed on the screen even if my fetch is well executed.
If I execute app.messages.toJSON() in my console, my data are returned as demanded.
Do you have any idea about it ? Here is my code
var app = window.app = {};
// APP HERE
// Model
app.Message = Backbone.Model.extend({
url : 'messages'
});
app.message = new app.Message;
// Collection
app.Messages = Backbone.Collection.extend({
model : app.Message,
url : 'messages'
});
// Views
app.messages = new app.Message();
app.messages.fetch();
app.ListView = Backbone.View.extend({
template : Handlebars.compile($('#template-list').html()),
initialize : function(){
_.bindAll(this, 'render');
//this.collection.on('reset', this.render);
},
render : function(){
this.$el.html(this.template({
collection : this.collection.toJSON()
}));
return this;
}
});
I'm breaking my teeth on it.
Simon
EDIT
After all this code I have
app.Router = Backbone.Router.extend({
routes: {
'*path' : 'home'
},
home: function(){
this.views = {};
this.views.list = new app.ListView({
collection : app.messages
});
$('#list-shell').empty().append(this.views.list.render().el);
}
});
app.router = new app.Router();
Backbone.history.start({pushState : true});
Backbone.emulateJSON = true;

app.messages = new app.Message(); I guess this is only a mistake you made while writing the question.
As for the question itself, if you're using Backbone 1.0, you'll have to use the reset flag if you want a reset event fired.
Furthermore, if the piece of code you added really is after the first one, you're fetching your data before creating the Router, therefore the view. Even if the fetching method is asynchronous, you're not controlling what you're doing here.

Related

Backbone API fetch() from Model using API authentication

I have problem with my Backbone mobile app (using Cordova, Require, Handlebars, etc..).
In particular the console log of chrome give me this result:
.
I've tried different solutions taken by debugging and searching on the web.
The first are defining the urlRoot in my Model.backbone and calling the function mymodel.fetch(). And the result given is: .
This is the code:
var MyModel = Backbone.Model.extend({
constructorName: "MyModel",
urlRoot: 'http://192.168.56.101/XXX/api/categories/26?io_format=JSON'
});
myView: function() {
var model = new MyModel();
model.fetch();
// create the view
var page = new MyView({
model: model
});
// show the view
this.changePage(page);
},
The second solution is embedding the API KEY in the urlRoot. Like that:
var MyModel = Backbone.Model.extend({
constructorName: "MyModel",
urlRoot: 'http://IYI6M35MLB8UVW38fhj9RY3YPQWRX5X8H#192.168.56.101/XXX/api/categories/26?io_format=JSON'
});
The last solution that we tried was passing the header in the fetch call. Like this code:
myView: function() {
var model = new MyModel();
model.fetch({
headers: {
'Authorization': 'Basic IYI6M35MLB8UVW38Y99RrgsrPQWRX5X8H:'
}
});
// create the view
var page = new MyView({
model: model
});
// show the view
this.changePage(page);
},
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
All of this solutions give me the same result, like "Chrome Console LOG", he sad me "Unauthorized etc.." like the image.
Can you give me some help? How can I bring JSON object in a model in Backbone using API with authentication by Username?

Backbone 101 - Using JSON data with backbone

I'm in the beginning stages of moving my application to the backbone framework.
I have some data that comes in as json from an ajax call
{f1:"f1_value", f2:"f2_value", f3:"f3_value"},
{f1:"f1_value", f2:"f2_value", f3:"f3_value"},
{f1:"f1_value", f2:"f2_value", f3:"f3_value"},
This data set always has 3 columns but may be as long as needed for each set as far as rows goes.
It is used to populate a div after processing it client side into HTML, which correlatively may extend down as far as needed. I was planning on this data chunk representing one view in the framework.
<div id = "data_hold"></div>
How do I match this up to the framework:
var ModelTest,
CollectionTest,
ViewTest;
ModelTest = Backbone.Model.extend({
});
CollectionTest = Backbone.Collection.extend({
model: ModelTest
}
ViewTest = Backbone.View.extend({
});
Backbone 101:
var ModelTest,
CollectionTest,
ViewTest;
ModelTest = Backbone.Model.extend({ });
// associate your collection with a URL. This is static here; it can be
// passed in as an option using the Collection's initialize function()
// instead.
CollectionTest = Backbone.Collection.extend({
model: ModelTest,
url: 'http://localhost/my_json_source'
});
ViewTest = Backbone.View.extend({
// Have a target to render into. This can be an existing element, as
// here, or it can be dynamically generated and attached to the DOM
// programattically.
el: $('#data_hold'),
// specify than when the collection is updated, call the local render
// method.
initialize: function(options) {
this.collection.bind('reset', _.bind(this.render, this));
},
// Empty the element, then append subsequent rows of the collection
// to it as paragraphs. The '_this = this' idiom allows us to access
// the outside context (the View's context), since the each() call
// will create a new inner context.
render: function() {
var _this = this;
this.$el.html('');
this.collection.each(function(l) {
_this.$el.append('<p>' + l.get('f2') + '</p>');
});
}
});
// initialize the collection and view, then fetch the collection, which
// will trigger the render after the collection has been updated.
$(function() {
ct = new CollectionTest();
vt = new ViewTest({collection: ct});
ct.fetch();
});

populate collection on Backbone

Tutorial.Views.Layout = Backbone.Layout.extend({
model: Tutorial.Model,
});
initialize: function () {
_.bindAll(this);
this.model = new Tutorial.Model({id : $("#data").data('user') });
this.collection = new Tutorial.Collection();
var success1 = function(){
console.log('OK');
};
this.collection.fetch({success : success1});
},
showTuto: function(){
step = this.collection.first(1);
console.log(step);
},
My problem is my collection is empty. My model has 4 items, but i see none of them .
Thanks in advance
We need to see some more code to make a closer suggestion, but hopefully this explanation will help you out. You should pass your model directly to the collection, OR deal with it in the fetch.
//simplified view
YourView = Backbone.View.extend({
initialize : function(){
var testModel = new Tutorial.Model({id : $("#data").data('user') });
this.collection = new Tutorial.Collection();
this.collection.add(testModel);
}
});
In this case, you would be adding that model directly to your collection. If you want to asyncronously call and get data from the fetch and then pass a callback, you could do something like this:
//simplified view
YourView = Backbone.View.extend({
initialize : function(){
this.collection = new Tutorial.Collection();
this.collection.fetch(function(){
console.log('okay');
});
}
});
Tutorial.Collection = Backbone.Collection.extend({
fetch : function(callback){
// grab a ref to your collection
var thisCollection = this;
// call your data function which has the ajax call
getYourDataFunction(function(data){
// if your data returned is an array of objects
thisCollection.add(data);
if (typeof callback === "function"){
//if you included a callback, call it with a reference to the collection
callback.call(thisCollection);
}
});
});
});

How do I render multiple records out to a html table with Backbone.js ?

var ContractModel = Backbone.Model.extend({
url: "${g.createLink(controller:'waiverContract', action:'index')}"
})
var contract = new ContractModel({});
contract.fetch();
var contracts = new Backbone.Collection.extend({
model: contract
});
var ContractView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function() {
var root = this.$el;
_.each(this.model, function(item) {
var row = '<tr><td>' + item + '</td></tr>';
root.find('tbody').append(row);
});
return this;
}
});
var cView = new ContractView({ model: contract, el: $('#contracts') });
I have Chrome's developer tools open. If I do a console.log(this.model) inside of the render function, I can see a mess of an object, of which the two records are stored in .attributes. But instead of two rows being added to the table, I get 7. 6 of which are objects. (Though I see 9 subobjects in Chrome's console).
Not much of this makes sense to me. Can anyone help me not only get this working, but also understand it? I know that render() fires off as soon as I have instantiated cView, and I know that it's doing the ajax as soon as I do .fetch() into the model. But that's the limit of what I can understand in this.
You should fetch and iterate on the collection, not the model. A model is one "thing" and a collection has many "things". Assuming you are fetching a JSON formatted array into your model, it will end up with properties like "1", "2", and so on, and each of these will just be a normal Javascript object, not a ContractModel instance.
Here is how you might restructure your code:
var ContractModel = Backbone.Model.extend();
var ContractCollection = Backbone.Collection.extend({
//ContractModel class, not an instance
model: ContractModel,
//Set the url property on the collection, not the model
url: "${g.createLink(controller:'waiverContract', action:'index')}"
})
var ContractView = Backbone.View.extend({
initialize: function(){
//Bind the collection reset event, gets fired when fetch complets
this.collection.on('reset', this.render, this);
},
render: function() {
//This finds the tbody element scoped to your view.
//This assumes you have already added a tbody to the view somehow.
//You might do this with something like
//this.$el.html('<table><tbody></tbody></table>');
var $tbody = this.$('tbody');
this.collection.each(function(contract) {
//Add any other contract properties here,
//as needed, by calling the get() model method
var row = '<tr><td>' + contract.get('someContractProperty') + '</td></tr>';
//Append the row to the tbody
$tbody.append(row);
});
return this;
}
});
//Instantiate collection here, and pass it to the view
var contracts = new ContractCollection();
var cView = new ContractView({
collection: contracts,
el: $('#contracts')
});
//Makes the AJAX call.
//Triggers reset on success, and causes the view to render.
//Assumes a JSON response format like:
// [ { ... }, { ... }, ... ]
contracts.fetch();

Problems with fetching and parsing using Backbone.js

I try to fetch this server: http://cshosting.webfactional.com/api/v1/projects/?format=json
to a backbone.js collection.
Then I try to console.log it, but it's not working.
It is very important to me, please help.
NEWS: I figured out it's something with JSONP. will be glad to hear more information about that. thanks.
this is parts of my code in short:
window.ProjectList = Backbone.Collection.extend({
model: Project,
url:"http://cshosting.webfactional.com/api/v1/projects",
parse: function(response) {
return response.objects;
}
});
another part:
window.HomeView = Backbone.View.extend({
initialize:function () {
this.projectList = new ProjectList();
this.projectList.fetch({success : function() {console.log(this.projectList); }});
this.homeListView = new HomeListView({model: this.projectList});
}
});
The this on the fetch callback is not going to refer to your HomeView instance. Try using another variable to ensure you are referencing the desired object.
initialize:function () {
var self = this;
this.projectList = new ProjectList();
this.projectList.fetch({success : function() {console.log(self.projectList); }});
this.homeListView = new HomeListView({model: this.projectList});
}
If that doesn't solve the problem, please describe what happens. Use the webkit inspector's network tab to make sure the correct GET request and response are being called. Make sure your parse function is being called and the response object is what you expect.
It seems like you would want to do something more like this:
window.Project = Backbone.Model.extend({
url:"http://cshosting.webfactional.com/api/v1/projects/?format=json"
});
window.ProjectList = Backbone.Collection.extend({
model: Project,
url:"http://cshosting.webfactional.com/api/v1/projects/?format=json"
});
window.HomeView = Backbone.View.extend({
initialize:function () {
_.bindAll(this, 'render');
},
render: function(){
var self = this;
console.log(self.collection);
return this;
}
});
var project = new Project();
var collection = new ProjectList();
collection.fetch({
success: function(result_collection, resp) {
var view = new HomeView ({ collection: result_collection });
view.render();
}
});

Categories

Resources