Backbone fetch single model attributes - backbone.js

im trying to fetch a single Models attributes. I use this model as kind of a config file for an app im currently building. But i cant get my head around how to get the attributes in a nice way.
The model looks like this:
WelcomeModel = Backbone.Model.extend({
url: "assets/json/config.json",
parse: function (response) {
return response.data;
}
});
The json looks liks this:
{
"data": [{
"companyName": "lorem ipsum",
"companyLogo": "loremipsum.png"
}]
}
And in my view i fetch it like this.
this.model = new WelcomeModel();
this.model.fetch({
success: function(model,response) {
console.log(model);
},
error: function() {
console.log('error')
}
});

1) parse method returns array instead object. Replace
return response.data
with
return response.data[0];
2) add defaults hash to your WelcomeModel model.
defaults: {
companyName: '',
companyLogo: ''
}

Related

Backbone collection different result strategy

Lets say I have method that returns from server 2 data sets:
On success:
{"status":true,"data":[{"id":1, "name": "yolo"}, {"id":2, "name": "yolo2"}]}
On fail:
{"status":false,"data":["Some error"]}
I use following collection:
var Entities.Collection = Backbone.Collection.extend({
url: "/entity",
model: Entities.Model,
parse: function(json) {
// return different data ?
// trigger something ?
return json.data;
}
});
The problem is when I have fail result after fetch it will set collection with error details.
What is the best practice to handle such issue ?
I'd say populate the collection only if you have a success scenario, which would look something like this:
var Entities.Collection = Backbone.Collection.extend({
url: "/entity",
model: Entities.Model,
parse: function(response) {
if(response.status)
return response.data;
else {} // handle this if you want to do something like triggering an event or
// setting a flag, else leave it
}
});

Backbone Model/Collection fetch does not store the result

its me again with another interesting Backbone.js question.
When I call Model#fetch() or Collection#fetch() then Backbone will call the server correct, but it will not store the result, but save works as intended.
In every tutorial I found they explain it that the model will be stored after fetch().
example
response contains 'success' and collection contains the XHR object with the correct json
tagCollection = new CategoryCollection();
tagCollection.fetch({
complete: function(collection, response) {
console.log(tagCollection.models);
},
});
code
/models/category.js
define(['underscore', 'backbone'], function(_, Backbone){
var CategoryModel = Backbone.Model.extend({
urlRoot: '/api/v1/category',
});
return CategoryModel
});
/collections/category.js
define(['underscore', 'backbone', 'categoryModel'], function(_, Backbone, CategoryModel){
var CategoryCollection = Backbone.Collection.extend({
model: CategoryModel,
url: '/api/v1/category'
});
return CategoryCollection
});
/api/v1/category(.json)
[
{
id: "1",
name: "Allgemeines",
deleted_at: null,
created_at: "2014-02-23 17:22:22",
updated_at: "2014-02-23 17:22:22"
}
]
Fetch accepts a 'success' callback rather than a 'complete' one. Assuming the data is coming backbone successfully from the server it's probably just not logging out because the callback isn't firing. Try this:
tagCollection.fetch({
success: function(collection, response) {
console.log(tagCollection.toJSON());
},
});

Setting Default Options for Backbone Collections

I have a Backbone Collection like so:
var ThreadCollection = Backbone.Collection.extend({
url: '/api/rest/thread/getList'
});
var myCollection = new ThreadCollection();
And then I'm fetching it from the server using the data object to append the query parameters (so in this case it comes out '/api/rest/thread/getList?userId=487343')
myCollection.fetch({
data: {
userId: 487343
}
})
There are other parameters that I may want to use instead of userId (groupId, orgId, etc) but I'd ideally define the data parameters upon initialization and from then on be able to run fetch() without specifying. Something like this:
var myCollection = new ThreadCollection({
data: {
userId: 487343
}
});
myCollection.fetch()
but it doesn't work. Does anyone know if there's a way to do this? Thanks!
One way is to define a custom fetch method on your collection which calls the super fetch method with some overridable defaults:
var ThreadCollection = Backbone.Collection.extend({
url: '/api/rest/thread/getList',
fetch: function(options) {
return Backbone.Collection.prototype.fetch.call(this, _.extend({
data: {
userId: 48743
}
}, options));
}
});
var myCollection = new ThreadCollection();
myCollection.fetch();

Backbone.js model: overwriting parse for custom API

In Backbone.js, I'm working with an API which wraps the response in a meta and data hash. For example:
# GET /api/posts/1
meta: {
status: 200
},
data: {
id: 1
title: 'Hello World'
}
# GET /api/posts
meta: {
status: 200
},
data: [
{
id: 1
title: 'Hello World'
},
{
id: 2
title: 'Hi everyone!'
}
]
My Backbone.js Collection/Models have the following parse function overwritten:
# App.Models.Post
...
parse: function (response) {
this.meta = response.meta;
return response.data;
}
# App.Collections.Posts
...
parse: function (response) {
this.meta = response.meta;
return response.data;
}
However, when I fetch on the collection posts = new App.Collections.Posts(); posts.fetch(), the post attributes are all empty. I.e. posts.at(0).get('title') = undefined.
Now, this is fixed when the Model parse is changed to:
parse: function (response) {
return response;
}
But this means that post.fetch() is broken.
Any suggestions?
Thanks!
I think the problem is that your model's parse is getting inconsistent data passed into it when done via model fetch vs collection fetch. console.log the argument to model parse to confirm this. This is because the value return by collection's parse is just an array of object data and to convert those to models, the collection just delegates to the model's parse method. This might fix your issue:
//App.Models.Post
parse: function (response) {
if (response.data) {
return response.data;
}
return response;
}
For reference: https://github.com/documentcloud/backbone/pull/773

Wrapping my head around a unique backbone.js collection

I'm working out my first backbone.js app and have run into a bit of a wall. Perhaps someone can help me past this hurdle (gap in my understanding). What I want/need to do is to return the collection data to my router, so I can bind it to a Kendo UI Grid, but I'm not seeing any of the search results in my collection... I figure I must be missing something fundamental, but I'm not sure what it is.
Here is what I have so far:
ES.Router = Backbone.Router.extend({routes: {
'': 'search',
'search': 'search',
'results': 'results'
},
results: function() {
var resultsData = new ES.Results();
var boo = resultsData.fetch({
data: JSON.stringify({"query":"myquery"}),
type: 'POST',
contentType: 'application/json'
});
console.log(boo);
}});
ES.Result = Backbone.Model.extend();
ES.Results = Backbone.Collection.extend({
model: ES.Result,
url: '/search/query'
});
There are a few issues here:
A fetch should be a GET, not a POST, because a fetch should not save or modify anything
Maybe just a personal preference, but I'd url as a function, so as to avoid trying to modify the AJAX request options manually.
The fetch call will always be asynchronous, so you need to either add a success callback in the options hash, or add a listener to the collection's reset event
I'd write the collection like this:
ES.Results = Backbone.Collection.extend({
initialize: function() {
this.query = "test";
},
model: ES.Result,
url: function() {
return '/search/query?query=' + this.query;
}
});
Then set the search when you create the collection:
var resultsData = new ES.Results();
resultsData.query = "soccer";
And use success and/or the on("reset") event to handle the result:
resultsData.on("reset", function(collection) {
console.log(collection);
});
console.log("Fetching....");
resultsData.fetch({
success: function(collection, response) {
console.log("Got data!" + collection.length);
},
error: function(collection, response) {
console.log("Error: " + response.responseText);
}
});
​

Resources