I am using backbone with Node and Express. I have my restful api set up to return my model and collection data. The api works fine. But I'm having trouble binding a route to one of my api paths.
I have a company model and collection so that when go to the routes you get the restful api data for that route:
http://localhost:3000/employees you get the data for restful api path api/employees
http://localhost:3000/employees/1 you get the data for restful api path api/employees/1
I also have a category model and collection to do the same:
http://localhost:3000/categories you get the data for restful api path api/categories
but the following does not work:
http://localhost:3000/categories/Auto you don't get the data for restful api path api/cateogries/Auto The restful api works and returns the right data, but the collection I get in my app returns the same data as the category collection called with the path api/cateogries. Almost like the path gets ignored.
Typically you have a collection and then you provide a id attribute to get a model that belongs to that collection. But what if you want a collection whose id attribute returns another collection? For example, you get a list of categories and then when you select a category you get a list of all the companies in that category? What is the right way to do this in backbone?
Thanks. I actually figured it out. I was returning a collection and needed to adust the url of my collection to point it to the correct path in my restful api. So in my collection I added a url function that goes to a different route if a parameter is passed into the constructor:
url:function(){
if(this.category1){
return "api/categories/"+this.category1;
}
return "api/categories";
},
initialize:function(opts){
this.category1=opts && opts.category1;
}
Related
I am attempting to implement a sample application with Angular that interacts with a backend REST API using $resource objects. However, the backend system does not generate id's for the resources, so these need to be defined on the objects being created on the client. This causes a problem when invoking the $save method on the new'ed resource because it forces the JSON data to be POSTed to the wrong URL, i.e., it POSTs to:
/resources/employees/1234
rather than:
/resources/employees
I would prefer not to have to drop down to using the low level $http service if I can avoid it.
Does anyone know how I can work around this issue?
Thanks.
This is because of the fact that you configured your $resource constructor in this way, for example:
$resource('resources/employees/:employeeId', {
employeeId: #id
});
That means that when you call methods like $save or $delete etc. on the resource objects made by this constructor, the variable :employeeId in the url will be filled with the value id that exist on the object on which you called the method. To avoid this you have to modify the constructor config so that the url variable does not depend on the object id property.
I am wondering if it's a good practice to use the same URL to provide both the HTML and JSON response.
For example if I am building a blog and I have a URL that provides the latest items, I would have a URL like /latest
I would like to use the same URL for my endpoint in angular to retrieve the items so I have following route in my node implementation:
app.get("/latest",function(req,res){
var type = req.header("Accept");
if(type.indexOf("application/json") > -1){
getLatestItems(req,res);
}
else {
res.render("/latest", {user: req.session.username, current: "latest"});
}
});
I was wondering if this approach is OK or is it better to have a separate set of endpoints for my JSON responses?
I would create a separate URL pattern for your backing API.
So in Angular you can still have a URL route /latest, but you will provide the JSON data via a URL like /api/latest.
This will create less confusion and also allow you to easily integrate the API with other stuff since it will only be returning JSON.
I use Rails 4 + backbone in my application.
Everything is good. New model is created in backbone and saved by calling:
newItem.save(null, {success: this.sendSuccess, error: this.sendError});
However, implementing a new feature I need to change one of the model attributes. What I see that a PUT action is fired just before sendSuccess is called, which I want to avoid.
Moreover, the url is very strange. Save action calls this url:
Remote Address:127.0.0.1:3000
Request URL:http://www.lvh.me:3000/api/user/1/tickets
Request Method:POST
and then, after server return the json with the modified attribute, backbone calls this url:
Remote Address:127.0.0.1:3000
Request URL:http://www.lvh.me:3000/api/user/1/tickets
Request Method:PUT
without the ticket id!
Is there any way to prevent backbone fire an update when server return the model with different attributes?
The problem was that I had a listener in my model exactly on the column that server changed:
initialize: function() {
this.on("change:status", this.statusChanged, this);
},
Now I had to figure out why the update url does not contain the model id.
I figured out that when I first created the model, from some reasons I couldn't assign it to the collection, so in order to save it I assign the url manually:
var newTicket = new MyApp.Ticket( ticketData );
newTicket.url = this.collection.url();
Now, the bug is that url is a function, and I simply overrided it!
I changed the code to:
newTicket.urlRoot = this.collection.url();
and now it works.
Backbone will always perform PUT if your model has an id attribute setted. Which makes sense when using RESTfull.
Be sure that you're really SAVING(new model withoud an ID) a data to server instead of UPDATING(model with an ID) to server.
Backbone.js sents an POST on updated objects instead of an PUT.
I think this is because mongoDB uses _id instead of id.
How do I say backbone.js to use _id instead of id?
I already tried some server-side change but I think it would be easier just to say that backbone should use another attribute as id.
MongoDB: output 'id' instead of '_id'
From the fine manual http://backbonejs.org/#Model-idAttribute
idAttribute model.idAttribute
A model's unique identifier is stored under the id attribute. If you're directly communicating with a
backend (CouchDB, MongoDB) that uses a different unique key, you may
set a Model's idAttribute to transparently map from that key to id.
Id attribute can be changed per model like
var Meal = Backbone.Model.extend({
idAttribute: "_id"
});
To make it default for all models (eg., if we are using mongodb), override the default setting by placing this LOC in your app js file that runs after backbone.js
//override the id attribute for model
Backbone.Model.prototype.idAttribute = '_id';
Currently I'm doing a local Backbone app. And I want to know how to save data, specifically, how to construct the url attribute for Collection and Model. I have created a folder called data which is intended to hold the data. But how is the data structured? Is it just a single json file to hold the whole Collection data in it? Or it has many seprate json files to hold each Model's data individually? If it's a single json file, how should I created the url atrributes for both Collection and Model? If they are many separate json files, What should I do?
It is upto you :) . Backbone.Js models, collections work and can be made to work with pretty much any type of data source that expose through HTTP and URL. But it was designed to work against REST based services out of the box. Since you are interested to test the library and learning it i will advice you to stick to static JSON file or even Twitter timeline service.
Since all collections are in single JSOn file you will need just to set the URl for the collection.
View that renders the collection will instantiate the models and render them from the collection
Application
window["Application"] = {};
Application.Model = {};
Application.Collection = {};
Application.Views = {};
Application.Templates = {};
Application.Router = {};
Collection from url
Application.Collection.TimeLine = Backbone.Collection.extend({
url:"data/collection.json"
});
Current Url is http://localhost/timelineapp/index.html
Collection.Fetch will make GET request to http://localhost/timelineapp/data/collection.json
is this not clear enough i will add more detail