Bakbone model extend filtering a json - javascript

I am very new in backbone js.
I am trying to filter some specific key and values in backbone js model extend here is the code below.
var items = ["open","close"];
var ReportModel = Backbone.Model.extend({
url: function() {
return tab+".json";
}
});
where tabe is dynamic json file name.In my json file many key value pair are there but I want to load only those key which is mentioned in items list.
I saw some where using parse function but that a;so did not work out.Please do let me know how to filter the specific keys form json using the backbone.
I also tried creating a dict from json and pass it to model like.
var ReportModel = Backbone.Model.extend({
"open":{.......}
});
but there I am getting issue.
throw new Error('A "url" property or function must be specified');
Please help me out with this.

You are missing some steps to be succesfull on your task.
First a note about the error: Backbone expects a string on the url property while you're passing a function. If you want to use a function to return your url dinamically use urlRoot.
Now onto the real coding:
since you talk about a json file that has multiple key value, maybe you should declare your model as a key-value object, and then create a Backbone.Collection that will wrap your models.
A Backbone.Collection expose a lot of utilities that can help us modeling the results, in this case by using the where() function of our collection you will be able to filter the data after you have retrieved from the remote file.
Alternatively to filter your collection if you need more control over the function you can always call the undescore function filter() .
Please refer to the official documentation of underscore and backbone, as you will find a lot of functions that can help you and most of them have an example that shows how to use them.
Now that we have everything lets create our Backbone.Collection that will wrap your already defined model:
var ReportCollection = Backbone.Collection.extend({
model: ReportModel,
urlRoot: function(){
return 'yoururl.json';
}
});
now if you want to filter the result you can simply fetch the collection and perform a filter on it:
var myReports = new ReportCollection();
//call the fetch method to retrieve the information from remote
myReports.fetch({success: function(){
//the collection has been fetched correctly, call the native where function with the key to be used as a filter.
var filteredElements = myReports.where({my_filter_key : my_filter_value});
});
in your filteredElements you will have an array of object made up of all the model that matched the key/value passed to the where function.
If you need a new Collection from that you just need to pass the result as argument: var filteredCollection = new ReportCollection(filteredElements);

You can use _.pick() in the parse method as shown below:
var items = ["open", "close"];
var ReportModel = Backbone.Model.extend({
url: function() {
return tab + ".json";
},
parse: function(response) {
return _.pick(response, items);
}
});

Related

interpreting backbone collection data that it received from an api controller

I'm trying to use a simple collection and view to write out data from my backbone collection to my website. I just want to iterate over the collection and display properties like Id, Name, etc. in my template.
My collection gets its data from an api controller(a sample of the data is shown below).
My limited knowledge leads me to guess that the api controller is returning an object and not JSON.
So I'm guessing that is messing up my results. I've written out the collection to my Chrome console and attached a screenshot of what I see below.
So looking at the code below, is there a way that I can format the data returned from the api so that my collection can use it effectively?
Here is the code:
var ResearchCollection = Backbone.Collection.extend({
url: '/api/lab',
getresearch: function() {
this.fetch({
url: this.url
});
}
});
var researchCollection = new ResearchCollection();
return Backbone.View.extend({
className: 'labRender',
template: _.template(tmpl, null, { variable: 'x' }),
render: function () {
researchCollection.getresearch();
console.log('collection: ', researchCollection);
}
Basically, I just want to iterate over my collection and display properties like Id, Name, etc. in my template.
Here is the raw data from the api controller that I am using to populate my collection:
{
"odata.metadata":"http://sol.edu/SOM/Api/v1/$metadata#ApiKeys","value":[
{
"odata.id":"http://sol.edu/SOM/Api/v1/ApiKeys('2f2627ed-3a97-43aa-ac77-92f227888835')","Id":"2f2627ed-3a97-43aa-ac77-92f227888835","Name":"VideoSearch","TimeoutInMinutes":20160,"IsDefault":false,"CreateAuthTicketsForResources":false,"ReportAuthFailureAsError":false,"ExcludePrivatePresentations":true,"Internal":true,"ViewOnlyAccessContext":true
}
]
}
when piped to the browser's console(why is each character a separate attribute?):
I think maybe this is because you mixed up collection and model. In Backbone, Model are fundamental unit, a Model can be used to render a template.However, Collection are ordered sets of 'Models'. So, if you just want to transform a data like you describe above, you may better select a Model instead of 'Collection'. Just try this:
var ResearchModel = Backbone.Model.extend({
initialize: function(attributes) {
this.url = 'api/lab'
}
});
// when you initialize a Model or collection, the first parameter is the attribute you want to initialize
var researchModel = new ResearchModel({});
return Backbone.View.extend({
className: 'labRender',
template: _.template(tmpl, null, { variable: 'x' }),
render: function () {
researchModel.fetch();
console.log('collection: ', researchModel);
}
Otherwise, if you just want to use collection, you had better specify its Model.Backbone use JSON, so you can also specify the model with your key.

Backbone: I am trying to fetch a collection (using a rails server). However, my fetch doesn't look to be working right

I am using a rails server that returns this JSON object when going to the '/todos' route.
[{"id":1,"description":"yo this is my todo","done":false,"user_id":null,"created_at":"2015-03-19T00:26:01.808Z","updated_at":"2015-03-19T00:26:01.808Z"},{"id":2,"description":"Shaurya is awesome","done":false,"user_id":null,"created_at":"2015-03-19T00:40:48.458Z","updated_at":"2015-03-19T00:40:48.458Z"},{"id":3,"description":"your car needs to be cleaned","done":false,"user_id":null,"created_at":"2015-03-19T00:41:08.527Z","updated_at":"2015-03-19T00:41:08.527Z"}]
I am using this code for my collection.
var app = app || {};
var TodoList = Backbone.Collection.extend({
model: app.Todo,
url: '/todos'
});
app.Todos = new TodoList();
However, when trying to fetch the data it states that the object is undefined. I originally thought that my function wasn't parsing the JSON correctly. However, that doesn't look to be the case. I created a parse function with a debugger in it to look at the response. In gives back, an array with three objects.
Here what happens when I try testing the fetch().
var todos = app.Todos.fetch()
todos.length // returns undefined
todos.get(1) // TypeError: undefined is not a function
The todos collection doesn't automatically populate the function get() in console. I am running out of ideas of what can be the problem. Please help. Thanks!
Fetch is a ayncronous, you need to listen to the add event:
var todos = app.Todos.fetch()
todos.on('add', function(model){
console.log(todos.length);
});
If you pass the parameter reset, you could listen for the would new models:
var todos = app.Todos.fetch({reset: true})
todos.on('reset', function(model){
console.log(todos.length);
});
You could also read here.
There are two problems:
Fetch is asynchronous; we don't know exactly when we'll have a result, but we do know that it won't be there when you are calling todos.length.
Fetch sets the collection's contents when it receives a response; calling app.Todos.fetch() will result in app.Todos containing whatever models were fetched by the request. Its return value is not useful for inspecting the collection, so var todos = app.Todos.fetch() won't give you what you want in any case.
If you want to inspect what you receive from the server, your best option is to set a success callback:
app.Todos.fetch({
success: function (collection, response, options) {
console.log(collection);
}
});

backbone.js is not saving model with updated attributes

usersCollection.fetch({
success: function () {
var getModel = usersCollection.where(checkIDJSON);
//update that partcular attribute
getModel.set('interest', 'rolling stones');
console.log("Users:" + usersCollection.toJSON());
},
error: function () {
// something is wrong..
}
});
After running the code, it complains that the function is undefined, when trying to save to the model. Any idea why? thanks
I am using backbone.js in titanium mobile
From the fine manual:
where collection.where(attributes)
Return an array of all the models in a collection that match the passed attributes.
So when you say this:
var getModel = usersCollection.where(checkIDJSON);
you end up with an array of models in getModel. If you're sure that there will only be one model that matches, then use findWhere:
findWhere collection.findWhere(attributes)
Just like where, but directly returns only the first model in the collection that matches the passed attributes.
like this:
var getModel = usersCollection.findWhere(checkIDJSON);
If there could be multiple matches then presumably you'd want to call set on each one.

Backbonejs - How can I print the results of a fetch?

Hi I'm new to Backbone and I was just playing around with it a little, here is my code:
var Users = Backbone.Collection.extend ({
url : 'http://backbonejs-beginner.herokuapp.com/users'
});
var users = new Users();
users.fetch({
success: function () {
console.log(users);
}
});
The fetch call succeeds and I am returned with an object that looks like:
[
{
"id": "hqel839m1071rbggsxf7",
"firstname": "Thomas",
"lastname": "Davis",
"age": 12
}
]
How can I print different parts of the result?
For example I want to print the "id" parameter of the first item. Can I iterate it like an array?
I tried to do console.log(users[0].id) but it doesn't work.
Thanks.
Not to forget about the arguments passed to success callback of collection.fetch which are (collection, response, options). Check documentation here. You can use the collection argument to select a particular model. Check below code :
var Users = Backbone.Collection.extend ({
url : 'http://backbonejs-beginner.herokuapp.com/users'
});
var users = new Users();
users.fetch({
success: function (collection, response, options) {
//Will log JSON objects of all User objects
console.log(collection.toJSON());
//You can get a Model using 'id'
var user = collection.get("hqesig1ea1br2k6horay");
// Will log User Model for id "hqesig1ea1br2k6horay"
console.log(user);
//You can then fetch Model attributes this way
console.log("ID: ", user.get('id'));
console.log("First name: ", user.get('firstname'));
console.log("Lastname : ", user.get('lastname'));
}
});
A fiddle for your reference.
There are three different ways to access the models in a Backbone.Collection. First, you can use the .get method to find a model based on it's unique ID. This basically looks at all models in the collection and compares their id attribute to the one provided.
var user = collection.get('unique_id'); // return an instance, or null
The second method is to use the .at method to get a model by index. This is useful if your models are sorted. If they are not sorted, they'll be fetched by insertion order (that is, the order in which they were provided to the collection):
var user = collection.at(0); // return the first model in the collection
Lastly, you can access the raw array of models that the Collection wraps. You can access this via the .models attribute, which is just an array. This is not the recommended approach.
var user = collection.models[0];
Once you have a user, you can access any attributes of the user via the .get method on your model:
var age = user.get("age");
user.set("age", 100);
You can view the documentation for the model get method here, and the documentation for Backbone.Collection here.

Backbone handle array of strings

Using Backbone.js I need to handle an array of strings returned from a JSON web service. Should I create a Backbone Collection to fetch this list? Here is the data I get from the web service:
["Question Designer","Adaptive Question Designer","Clickable image map","Essay","Fill in the blanks","Maple-graded","Matching","Mathematical formula","Multipart question","Multiple choice","Multiple selection","Numeric","Palette-based symbolic editor","True/false","Other"]
I've created this simple Collection to fetch the data:
var questionTypesCollection = Backbone.Collection.extend({
url: function() {
return apiBase + '/questions/types';
}
});
But when I try to fetch() the collection, I get this error:
Uncaught TypeError: Cannot use 'in' operator to search for 'id' in Question Designer
It looks like Backbone is trying to parse the strings as a model instead of seeing that it's just a raw string. How can I get the data into a Collection so I can use it in a View?
If you just need the strings, your best bet might be to just let jQuery (or Zepto--whatever has the $) handle the heavy lifting:
var names = [];
$.get(apiBase + '/questions/types', {}, function(result){
names = result;
})
After the fetch completes, the names variable will be populated with the results of your query.
This doesn't make a lot of sense, since backbone collection is designed to be, well, a collection of models.
However, you could override the parse method with your own parser.

Categories