Where is the result of fetch backbone? - javascript

I've fetched a collection in backbone by a apirest on parse.com but in the console.log i can read this result:
child {collection: child, attributes: Object, _escapedAttributes: Object, cid: "c2", changed: Object…}.
So where is the result??In my collection there are user with name,username ecc..
var HomeView = Backbone.View.extend({
template: Handlebars.compile(template),
events: {
},
initialize: function() {
console.log("inhomeview");
var amici = new Usercollection();
amici.fetch({
success: function(collection) {
amici.each(function(object) {
console.warn(object);
console.log(object);
});
},
error: function(amici, error) {
// The collection could not be retrieved.
}
});
Collection:
var Usercollection = Backbone.Collection.extend({
model:Person,
url:'https://api.parse.com/1/classes/User',
Model:
var Person = Backbone.Model.extend({
defaults:{
},
initialize:function(){
console.log("inperson");
},
validate:function(){
console.log("validate");
},
send:function(){
var user = new Parse.User();
user.set("username", this.get("username"));
user.set("password", this.get("password"));
user.set("email", this.get("email"));
// other fields can be set just like with Parse.Object
//user.set("phone", "415-392-0202");
user.signUp(null, {
success: function(user) {
// Hooray! Let them use the app now.
},
error: function(user, error) {
// Show the error message somewhere and let the user try again.
alert("Error: " + error.code + " " + error.message);
}
});
}
});
return Person;
});

amici.models contains the objects you are pulling
each model is a Person
initialize: function() {
var amici = new Usercollection();
amici.fetch({
success: function(collection) {
amici.models.each(function(person) {
console.log(person);
console.log(person.attributes);
});
},
error: function(amici, error) {
}
});
}

The objects you are printing to the console are instances of the Person model. That is what happens when you ask a collection to fetch data. It fetches data from the server, converts that data into model instances, and stores a list of those model instances as the collection contents. Perhaps you can further clarify your question.

Related

Backbonejs: Customise the model object before being sent/synced to the server

Am parsing data coming from the servers through the parse method provided by backbone.
var the_model = Backbone.Model.extend({
parse: function(response) {
return {
id: ApiWrapper.getId(response.resource_uri),
resourceUri: response.resource_uri,
categoryId: response.alert_type_id,
latitude: response.latitude,
longitude: response.longitude,
utm: MapCoordinates.latLongToUTM(response.latitude, response.longitude),
categoryName: response.alert_type_name,
ranger: {
fullName: response.ranger_id.first_name + ' ' + response.ranger_id.last_name
},
icon: "/images/map-icons/map-alert-0" + response.alert_type_id + ".png",
dateTime: moment(response.time_stamp).format("dddd, MMMM Do YYYY, h:mm:ss a")
}
}
});
var collection = Backbone.Collection.extend({
model: the_model
parse: function(data_from_server) {
return data_from_server.results
}
})
In order to sync any newly added data back to the server - since the server will not accept the parsed format backbone persists - how would I go by this? Practically un-parse the data or reformat the model(s) before being synced to the server.
To control how your model sends back data to your server, override Model.sync and set the attrs attribute in the options :
var the_model = Backbone.Model.extend({
parse: function(response) {
// ...
},
sync: function(method, model, options) {
options = options || {};
if ((method==='create') || (method==='update')) {
// prepare the data you want to send
var data = {
resource_uri: this.get('resourceUri'),
alert_type_id: this.get('categoryId')
// other attributes you want to add
};
// pass that as an option to Backbone.sync
options.attrs = data;
}
return Backbone.Model.prototype.sync.call(this, method, model, options);
}
});
And a demo http://jsfiddle.net/nikoshr/z31k1qtp/

Backbone fetch not fetching correctly

I seem to be fetching correctly from the server using backbone. A GET request is made to a MongDB collection, via the Node.js server code here:
exports.getTeams = function(req,res,next){
var system_db = req.system_db;
var user_id = req.mainUser._id;
var teams = teamModel.getNewTeam(system_db,user_id);
teams.find({}, function (err, items) {
res.json(items);
});
};
I am fetching from Backbone like so:
var teamCollection = new TeamCollection([]);
teamCollection.url = '/api/teams';
teamCollection.fetch(
{success:function(){
console.log('teamCollection length:',teamCollection.length);
console.log('teamCollection[0]:',teamCollection[0]);
}}
);
using this model and collection:
var Team = Backbone.Model.extend({
idAttribute: "_id",
urlRoot: 'http://localhost:3000/api/teams'
});
var TeamCollection = Backbone.Collection.extend({
model: Team,
initialize: function() {
this.bind('add', this.onModelAdded, this);
this.bind('remove', this.onModelRemoved, this);
this.bind("change", this.onModelChanged, this);
},
/* parse: function(data) {
//return JSON.stringify(data).objects;
//return JSON.parse(data).objects;
return data.objects;
},*/
onModelAdded: function(model, collection, options) {
console.log("added, options:", options);
},
onModelRemoved: function (model, collection, options) {
console.log("removed, options:", options);
},
onModelChanged: function (model, collection, options) {
console.log('Collection has changed.');
},
comparator: function (model) {
return model.get("_id");
}
});
the problem is that the logging statements above log the following in the browser console:
It says I am sending 4 items from the server to the Backbone client, but the first one is undefined. How could this be?
A Backbone.Collection is not an array-like object : it has a length attribute representing the number of models but you can't access individual models via indexes, hence
console.log(teamCollection[0]); //undefined
To get a model at a given position, use collection.at .Try
console.log(teamCollection.at(0));
And a demo of those behaviors http://jsfiddle.net/nikoshr/013gjpny/

Backbone: how to load a Collection in the view (inc require)

I am trying to load data from an API into a view. However the data doesn't turn up in my view.
I tried getting the collection information in de router, as well as in the model.
However the date won't even console.log the data. Let alone that I can load the data into the view.
I am using require to load the JavaScript files. Can you have a look and see what I am doing wrong here?
I do see this console.log:
console.log("People Collection is initialized");
And I can also see the page loaded and the json. But not the console.log of the data in the url function... In fact I get this error in the console:
Error: A "url" property or function must be specified
In the Backbone Router:
var OF = OF || {};
OF.AdminRouter = Backbone.Router.extend({
routes: {
"users": "goToUsers",
"users/*other": "goToUsers"
},
goToUsers: function() {
require(['./models/users', './views/users_view', './views/menu_view', './collections/user_collection'], function(UsersMdl, UsersView, MenuView, UsersCollection) {
OF.usersView = new OF.UsersView;
OF.usersView.render();
});
}
});
The Collection:
var OF = OF || {};
OF.UsersCollection = Backbone.Collection.extend({
initialize: function() {
console.log("People Collection is initialized");
},
url: function() {
var that = this;
var sendObj = {
"admin": OF.login.attributes.admin,
"session": OF.login.attributes.session
};
$.ajax({
url: 'php/api/users/',
type: "POST",
dataType: "json",
data: sendObj,
success: function(data) {
console.log(data);
},
error: function(data) {
console.log("ERR: " + data);
}
});
},
model: OF.UsersMdl
});
The Model:
var OF = OF || {};
OF.UsersMdl = Backbone.Model.extend({
default: {
username: '',
homefoldersize: '',
email: ''
},
initialize: function(){
//on change functions can be done here
OF.usersCollection = new OF.UsersCollection();
OF.usersCollection.fetch();
},
result: {
success: false,
message: ''
},
validate: function(att) {
}
});
The View:
var OF = OF || {};
OF.UsersView = Backbone.View.extend({
el: '#content',
remove: function() {
this.$el.empty();
this.stopListening();
return this;
},
initialize: function() {
//set the new address variable.
OF.usersMdl = OF.usersMdl || new OF.UsersMdl();
},
render: function() {
/*
//first check if you are allowed to see this page
if (!OF.login || !OF.login.isValid()) {
OF.router.navigate('login', {trigger: true});
return;
}
*/
//save this in that
var that = this;
//when importing of login page (and fill it with info) is done
$.when(OF.template.get('users-usersField', function(data) {
var htmlSource = $(data).html();
var template = Handlebars.compile(htmlSource);
var compiled = template(OF.usersMdl.attributes);
//now place the page
that.$el.html(compiled);
//then start the menu
})).then(function(){
setTimeout(function(){
OF.menuView = new OF.MenuView;
OF.menuView.render();
}, 100);
});
$('#logout').show();
}
});
Thanks.
It seems to call the initialize of the collection twice and then continues to call the json function.
In your model's initialization you have
OF.usersCollection = new OF.UsersCollection();
OF.usersCollection.fetch();
But when you fetch your collection, it's going to initialize models for every result it gets back ... which will then trigger fresh collection fetches.
You don't need to create collections for your models inside your models, especially if the model is being created by the collection. Whenever you add a model to a collection (including when the collection creates the model after a fetch) the collection will associate itself with the model.
The general order of things should be:
You define a url function on your collection which returns the URL where you can get the (raw JSON) models of that collection.
You instantiate that collection, and then call fetch on the instance
The collection makes an AJAX call (which you can affect by overriding fetch or sync) and gets back the raw JSON for all of the models.
The collection instantiates new models for each result it gets back; those models are automatically added to the collection, and their .collection is automatically set to the collection.
Once OF.usersCollection.fetch().done(function() {... you can have your views start doing things, as your collection should now be all set.

backbone save to server parse.com

i'm using backbone method save to update user object on parse.com. object that in backbone are based on a model and collection. When i fetch it's all right but when save appear: PUT https://api.parse.com/1/classes/_User/xj3QLLYy07 400 (Bad Request)
{"code":206,"error":"Parse::UserCannotBeAlteredWithoutSessionError"}
Model:
var Person = Backbone.Model.extend({
urlRoot: "https://api.parse.com/1/classes/_User/",
idAttribute: "objectId",
defaults:{
},
initialize: function() {
console.log("inperson");
// this.upload();
}
});
return Person;
Collection:
var Usercollection = Backbone.Collection.extend({
model: Person,
url:'https://api.parse.com/1/classes/_User/',
parse: function(data) {
return data.results;
}
});
return Usercollection;
and the code where i try to save the model:
this.model.save({email:"ciao#lib.it"}, {
// wait:true,
success:function(model, response) {
console.log('Successfully saved!');
},
error: function(model, error) {
console.log(model.toJSON());
console.log(error.responseText);
}
});
I think this answer needs an update. Cant you just swap the backbone collection and model to Parse's ones?
Here is a short example that worked for me today

In Backbone.js, how can I fetch data from a URL?

I'm trying to get tweets to pull from a URL, which returns data in the form of:
[
{"user":"someuser1","tweet":"this is a #tweet","date":"2011-09 02"},
{"user":"someuser2","tweet":"and this is a #tweet","date":"2011-09 02"},
{"user":"someuser3","tweet":"and this is another #tweet","date":"2011-09"}
]
I have a model,
window.Tweet = Backbone.Model.extend({
initialize: function(){
this.bind('change',function(){
})
},
defaults: {
"user": "some-other-user",
"tweet": "this is some tweet",
"date" : "2012-01-06"
}
});
I have a collection,
window.Tweets = Backbone.Collection.extend(null,{
url: '/tweets/',
model: Tweet,
parse: function(response) {
return response.results;
}
});
and I have a view
window.TweetsView = Backbone.View.extend({
el: $('#content-top'),
initialize: function(){
this.model.bind('change',this.render,this);
},
render: function() {
var TweetsCollection = Backbone.Collection.extend({
model : Tweet,
url: '/tweets/',
parse: function(response) {
return response.results;
}
});
var tweets = new TweetsCollection;
tweets.fetch();
console.log(tweets.toJSON());
} ...
Both
alert(tweets.at(0));
and
alert(tweets.length)
give me "Undefined." What am I missing?
EDIT
If I log the response (in the view), I do get something back:
[object Object],[object Object],[object Object]
so, I'm close, but still missing something.
Based on your comments, I would say the data is coming in right.
Try adding console.log(response); in your parse function.
In my backbone models, the parse() method just returns the first argument, which would be response in your case. I think you need to just change
return response.results;
to
return response;

Categories