this.save in backbone - backbone.js

I am on way to learning backbonejs.
I am working with the popular todo list tutorial.
I have certain questions about which i am a bit confused:
In one the models i found this function:
toggle: function() { this.save({completed: !this.get(’completed’)});}
The thing that i don't understand is this.save function. How does it work? What does it actually saves and where. And what does the code inside this function means: completed: !this.get and so on.
In one of the views i found this line of code:
this.input = this.$(’#new-todo’);
Now what does this.input means? And i also don't understand the sytnax this.$('#new-todo');
Let me know if more code is needed for comprehension. Also if anyone could point me to great learning resources for backbone, it will be awesome. Currently i am learning from 'Backbone Fundamentals' by addyosmani.

Backbone Model and Collection both have url properties.
When set properly backbone will make a HTTP POST request with the model as a payload to the url when saved for the first time (id property has not peen set). I you call save and the models id has been already set, backbone will by default make PUT request to the url. Models fetch function generates a GET request and delete a DELETE request.
This is how backbone is made to work with RESTfull JSON interfaces.
When saving a model you can define the actual model to save like it's done in the example.
Read the Backbone.js documentation. It's ok!

http://backbonejs.org/#View-dollar
this.$('#new-todo') // this.$el.find('#new-todo')

toggle: function() { this.save({completed: !this.get(’completed’)});}
Its basically saving inverse value to "completed" attribute of model. so if model's current attribute is true, it would save it to false !
regarding this.input = this.$(’#new-todo’);
Its basically saving/caching DOM with id "new-todo" from current VIEW's 'el' to view instance's 'input' property. so that we do not have to call jQuery methods for getting the same element when we need in future.
hope this helps.

:)
I too am a backbone newbie and i had been in search of good tutorials that gave good insights into the basics and i found after around 3-4 days of searching. Go through backbonetutorials.com and there is a video compiled which gives exactly what we need to know about Routers, Collections, Views and Models.
The sample working can be found at : http://backbonetutorials.com/videos/beginner/
Although this tutorial is a very basic one, you need to have basic jquery, javascript knowledge. Keep http://www.jquery.com opened in another tab as well when you go through the sample codes. Documentation is extremely useful.
Once you have good knowledge of jquery then if you go through the tutorials, you will understand and pick it up a lot better. And once you get hold of the MV* pattern of backbone you'll love it.
p.s : Do not copy paste codes or functions if you need to learn, type them.!!..
Cheers
Roy

toggle: function() { this.save({completed: !this.get(’completed’)});}
Backbone Model have a url property, when you set a property backbone makes a HTTP request to that url to save that value to the data source.
Here it is setting the value of "completed" attribute with inverse of earlier "completed" value, which will be saved to the data source

Related

What is the correct way of handling angular resource 1.2.x get queries?

I am currently working on implementing a REST API with Angular resource 1.2.x. I just came across several hints that with the 1.2.x release, angular-resource broke some existing patterns. My question is now, how to handle the following scenario with angular-resource 1.2.x correctly.
I do have a REST API that returns data (/offers/:id) and a angular service that abstracts those API by using angular-resource. Within this service I do have a get function that queries the API with the given id:
_offerResource.get({offerId: id})
The _offerResource itself is an instance of $resource.
In my controller, I do have a variable offer on the $scope to which the view is bound (e.g. $scope.offer.title, ...).
I tried to implement the call to the API with the following line of code:
_tempOffer = OfferAPI.get($routeParams.offerId)
But unfortunately the bindings are not working. Based on this SO entry (Angularjs promise not binding to template in 1.2) the behavior of angular-resource has changed. But is the approach with using the $promise.then(...) statement the way to go? From an engineering point of view this looks quite ugly, as I need to take care of this in the controller, rather than the service returning me an object that I just can use.
This one works, but as stated above, it is not my favorite approach from a SW design point of view:
_tempOffer = OfferAPI.get($routeParams.offerId)
_tempOffer.$promise.then((response) ->
$scope.offer = Offer.initializeFromJSON(response.offer)
)
I convert the response of the API into another object btw, so I need to have the following transformation before I can bind the offer object to the $scope.offer variable:
$scope.offer = Offer.initializeFromJSON(response.offer)
Thanks a lot for your help!

How to return/edit REST resource with AngularJS & Restangular

Using Restangular for AngularJS, keep getting an object object from Mongolab.
I'm sure it has to do with Promise but not sure how to use/implement this coming from old Java OO experience.
(Side note, would something like Eloquent Javascript, some book or resource help me understand the 'new' Javascript style?)
The small web app is for Disabled Students and is to input/edit the students, update the time they spend after school and then output reports for their parents/caregivers every week.
Here's the code that returns undefined when popping up a new form (AngularJS Boostrap UI modal)
I personally think Restangular & the documentation is a great addition so hope it doesn't dissuade others - this is just me not knowing enough.
Thanks in advance
app.js
...
$scope.editStudent = function(id) {
$scope.myStudent = Restangular.one("students", id);
console.log($scope.myStudent);
}
I'm the creator of Restangular :). Maybe I can help you a bit with this.
So, first thing you need to do is to configure the baseUrl for Restangular. For MongoLab you usually do have a base url that's similar to all of them.
Once you got that working, you need to check the format of the response:
If your response is wrapped in another object or envelope, you need to "unwrap" it in your responseExtractor. For that, check out https://github.com/mgonto/restangular#my-response-is-actually-wrapped-with-some-metadata-how-do-i-get-the-data-in-that-case
Once you got that OK, you can start doing requests.
All Restangular requests return a Promise. Angular's templates are able to handle Promises and they're able to show the promise result in the HTML. So, if the promise isn't yet solved, it shows nothing and once you get the data from the server, it's shown in the template.
If what you want to do is to edit the object you get and then do a put, in that case, you cannot work with the promise, as you need to change values.
If that's the case, you need to assign the result of the promise to a $scope variable.
For that, you can do:
Restangular.one("students", id).get().then(function(serverStudent) {
$scope.myStudent = serverStudent;
});
This way, once the server returns the student, you'll assign this to the scope variable.
Hope this helps! Otherwise comment me here!
Also check out this example with MongoLab maybe it'll help you :)
http://plnkr.co/edit/d6yDka?p=preview

Backbone view based on model from collection, how to update view?

I am looking for a bit of direction I am still fairly new to Backbone and am currently creating a test application to learn more.
My problem is this, I am populating a backbone view with a underscore template. I load a collection of models, then I find the model I need and populate these values into the template. There can be many pages based on the template so I have a dynamic route that accepts an id.
My problem is I want to add a next feature, that would change the current page and reload the template with the new model.
I have tried a crude method along the lines of :
Backbone.history.navigate(newLocation)
However this did'nt work, please note newLocation is actually populated with the route and the id I want to navigate to.
I will add some code from my view below, I won't include the full code however if it is needed please ask.
Any help or a push in the right direction would be great.
Thanks in advance
You need to use your router object's navigate method rather than than history's class method, and you need to pass it the option `{trigger: true} in order to invoke the corresponding route function.

Using Backbone models with AngularJS

Recently I was thinking about the differences and similarities between Backbone.js and AngularJS.
What I find really convenient in Backbone are the Backbone-Models and the Backbone-Collections. You just have to set the urlRoot and then the communication with the backend-server via Ajax basically works.
Shouldn't it be possible to use just the Backbone-Models and Collections in AngularJS application?
So we would have the best of both worlds two-way data-binding with AngularJS and convenient access to the server-side (or other storage options) through Backbone-Models and Collections.
A quick internet search didn't turn up any site suggesting this usage scenario.
All resources either talk about using either the one or the other framework.
Does someone have experience with using Backbone-Models or Collections with AngularJS.
Wouldn't they complement each other nicely? Am I something missing?
a working binding for example above...
http://jsbin.com/ivumuz/2/edit
it demonstrates a way for working around Backbone Models with AngularJS.
but setters/getters connection would be better.
Had a similar idea in mind and came up with this idea:
Add just a getter and setter for ever model attribute.
Backbone.ngModel = Backbone.Model.extend({
initialize: function (opt) {
_.each(opt, function (value, key) {
Object.defineProperty(this, key, {
get: function () {
return this.get(key)
},
set: function (value) {
this.set(key, value);
},
enumerable: true,
configurable: true
});
}, this);
}
});
See the fiddle: http://jsfiddle.net/HszLj/
I was wondering if anyone had done this too. In my most recent / first angular app, I found Angular to be pretty lacking in models and collections (unless I am missing something of course!). Sure you can pull data from the server using $http or $resource, but what if you want to add custom methods/properties to your models or collections. For example, say you have a collections of cars, and you want to calculate the total cost. Something like this:
With a Backbone Collection, this would be pretty easy to implement:
carCollection.getTotalCost()
But in Angular, you'd probably have to wrap your custom method in a service and pass your collection to it, like this:
carCollectionService.getTotalCost(carCollection)
I like the Backbone approach because it reads cleaner in my opinion. Getting the 2 way data binding is tricky though. Check out this JSBin example.
http://jsbin.com/ovowav/1/edit
When you edit the numbers, collection.totalCost wont update because the car.cost properties are not getting set via model.set().
Instead, I basically used my own constructors/"classes" for models and collections, copied a subset of Backbone's API from Backbone.Model and Backbone.Collection, and modified my custom constructors/classes so that it would work with Angular's data binding.
Try taking a look at restangular.
I have not implemented it anywhere, but I saw a talk on it a few days ago. It seems to solve the same problem in an angular way.
Video: http://www.youtube.com/watch?v=eGrpnt2VQ3s
Valid question for sure.
Lot of limitations with the current implementation of $resource, which among others doesn't have internal collection management like Backbone.Collection. Having written my own collection/resource management layer in angular (using $http, not $resource), I'm now seeing if I can substitute much of the boilerplate internals for backbone collections and models.
So far the fetching and adding part is flawless and saves code, but the binding those backbone models (or the attributes within, rather) to ng-models on inputs for editing is not yet working.
#ericclemmons (github) has done the same thing and got the two to marry well - I'll ask him, get my test working, and post the conclusion...
I was wondering the same-
This is the use-case:
salesforce mobile sdk (hybrid) has a feature called smartstore/smartsync, that expects backbone models/collection ,which gets saved to local storage for offline access .
And you guessed it right, we want to use angularjs for rest of the hybrid app.
Valid question.
-Sree
You should look at the angularJS boilerplate with parse here. Parse is backbone like, but not exactly backbone. Thats where im starting my idea of a angularJS backboneJS project

Backbone.js model validate method fails to fire

I'm trying to understand how Backbone.js model validation works, but I'm seeing some odd inconsistencies. In one place in my app, the validate method is getting called as expected. In another place, however, Backbone.js seems to be passing in a { silent: true } object to the validator, even though I don't want it to.
Here's a jsFiddle that illustrates the issue. The validate method should be called When the Copy buttons are clicked or the values change, but when I step through the code it's clear that the _validate function is being passed the { silent: true } option.
What am I missing?
Update: Figured out what was going on here. I created this jsFiddle originally to replicate an issue I was having that was actually the opposite of this question--I was trying to add an empty model to a collection and validation was firing and preventing me from doing so. When I made the Fiddle, though, it worked as I wanted my app to work. Validation wasn't firing when an empty model was added. I couldn't figure out the difference.
Turns out I was using Backbone.js 0.9.0 in my application and version 0.9.1 in my jsFiddle. Jeremy made changes to validation in 0.9.1 to make it work the way I wanted it to work in my app (see this issue on GitHub). Mystery solved.
Backbone specifically does not call _validate when you're making a new model.
Jeremy suggests that you do:
var mymodel = new MyModel();
mymodel.set({params});
Here's our exchange on github: can't override silent:true
From the Backbone docs, it seems you have to either call set or save on the model in order for validate to trigger.
I updated the jsfiddle so that set is called, and the now the validation function gets triggered:
http://jsfiddle.net/J3uuH/12/

Resources