Backbone fetching a collection using callbacks vs promises - ajax

I have a Location collection, and I have back a JSON response from the serve r on fetch including the root title with format:
{'locations':[
{
"id": 1,
"address": 'first address'
},{
"id": 2,
"address": 'second address'
}
]}
I've read everywhere that is best practice to use promise's methods over backbone success and error callbacks but here is the thing. I have override the parse method on the Location collection to return the array, but it appears that using the promises methods the parse method isn't called at all. So for example:
var Locations = new Backbone.Collection.extend({...})
var locations = new Locations()
locations.fetch().then(function(response){
console.log(response)
})
returns an Object literal with property locations which has the value of the Array of locations. But if I use
locations.fetch({
success: function(response){
console.log(response)
}
})
I get the wanted behavior, that is the object with constructor Locations and all the models in it.
Plus if I remove the root title of the JSON response on the backend and remove the parse method override on the collection, with the promise methods I'm getting an object with constructor Array, while with the success callback I'm getting an object with constructor Locations.
So my question is, if it is better to use the promise's methods how to adopt them with the similar behavior as the success and error callbacks?
Requsted update:
Here is the parse function in the Locations collections
var Locations = new Backbone.Collection.extend({
parse: function(response){
return response['locations']
}
})

Use the collection directly:
locations.fetch().then(function(){
console.log(locations);
})
The fetch method returns the jqXHR promise that makes the request, so it returns the raw response received from the server. The promise doesn't know about the parsing of the response.
The reason that passing a success callback as an option to fetch worked for you is: (See Collection.fetch documentation)
The options hash takes success and error callbacks which will both be passed (collection, response, options) as arguments.
So if use pass a success callback to fetch, the first argument is actually collection, not response.

Related

how to get request data in ajax success callback method

I do ajax request in foreach and question is that how to get request data in success callback or how to match response data and request.
Thank you in advance!
Something like this:
var makeRequest = function(data){
doAjaxRequest(data, function(dataFromServer){
console.log(data);
});
}
array.forEach(function(element){
makeRequest(element.getData());
}
What this does is for each element in array, the variable data is different because it refers to the local scope of the function makeRequest. This way, each callback refers to the proper data.

Unable to consume an Angular service from a Controller

So I've done extensive research and read many tutorials but I can't find a straightforward answer to what I'm trying to accomplish.
I'm simply trying to access a JSON object stored at JSON-Generator.com and stick it in a table and repeat it. Sounds simple enough but it seems there many different ways to do this and all the sources leave out the one piece of info I need.
if I console.log eventsService inside the controller it returns a constructor, if I console.log eventsService.data it returns undefined.
How do I access the data returned from $http in my controller?
// CONTROLLERS
app.controller('currentTradeshowsController', ['$scope', 'eventsService', function($scope, eventsService){
$scope.events = eventsService.data;
}]);
// SERVICES
app.service('eventsService',function($http){
var eventsUrl = 'http://www.json-generator.com/j/bVWJaYaWoO?indent=4';
$http({method: 'GET', url: eventsUrl}).
success(function(data){
// not sure what to write here....
return data;
})
.error(function(){
console.log('ah shit');
})
});
first of all, $http call is asynchronous, so you probably want to use promises to load the data correctly into scope variable
second - you need to return something from the service to make it work outside of the service declaration function
controller
app.controller('currentTradeshowsController', function($scope, eventsService){
eventsService.getData().then(function(data) {
$scope.events = data;
});
});
service
app.service('eventsService',function($http){
var eventsUrl = 'http://www.json-generator.com/j/bVWJaYaWoO?indent=4';
return {
getData: function() {
return $http.get(eventsUrl);
}
}
});
$http.get is a shorthand for GET request, and it returns a promise, so you can simply use it with .then in the controller

How to manipulate async scope in angularjs

I have this defined in controller
$scope.files = {};
Then I have a ajax call to get data and pass to $scope.files;
In the same controller. I have a ng-click function which I want to manipulate $scope.files
How to do that because it is async. I tried and the $scope.files always return blank {}
$scope.click = function() {
//Do something to $scope.files;
}
My fault. this is not related to async. I can actually get the data.
My problem is the return data is object and I tried to use .length to get the length of object so it always return 0 and {}. And I found .length for array.
and Object.keys(a) for object sizes
Looks like you need to use promise/deferred implementation. Promises allow you to execute code and once the promise is returned then continue.

Ajax call return json to model I can use data from in my own function

New to Backbone, so I may be over/under complicating things. (built spa's with my own functions in the past)
Psudo code of what I used to do:
AjaxCall(
url: "get json result"
success:
parse json
call Update(json.a, json.b)
)
function Update(a, b){
//do something with a/b var's
}
For a more abstract idea of what I am envisioning atm. If I click an update button, I want it to hit the server and return a success/fail status along with an Id and a message (imagining all in json format).
Found a few examples, but none seem to fit so far.
To do that, you'd use a Backbone model:
var Message = Backbone.Model.extend({
urlRoot: "messages"
});
var myMessage = new Message();
myMessage.save({}, {
success: function(model, response, options){
// code...
},
error: function(model, xhr, options){
// code...
}
});
Basically: the model configures the API call, and save will use backbone's sync layer to handle the actual AJAX. You can pass success and error callbacks to the `save function.
The first parameter to the save function are the attributes which are to be saved (see http://backbonejs.org/#Model-save), which seem to need to be empty according to your question.
Since the model instance has no id attribute, the save call will trigger a POST request to the API. If by any chance you actually need to provide an id (so that a PUT call gets triggered instead), simply do
myMessage.save({id: 15}, {
success: function(model, response, options){
// code...
},
error: function(model, xhr, options){
// code...
}
});

Ajax request, should it be POST or PUT

I have created a Spring MVC web app.
The app makes a few calls to the controller. These calls are close/open/end game.
I make these calls using Ajax, so I can handle a response on the top of the page.
ajaxPost = function (url, action, id, onSuccess, onError) {
$.ajax({
type: "POST",
url: url + "?" + action + "=" + id,
success: function(response) {
if(onSuccess !== null) {
onSuccess(response);
}
},
error: function(e) {
if(onError !== null) {
onError(e);
}
}
});
};
The question I have is that I'm using 'POST' for the Ajax request, is that correct, or should it be 'PUT'?
My controller has a default URL, and I'm using the param attribute to decide which method to call, as I have many buttons on the page.
#RequestMapping(params = "open", method = RequestMethod.POST)
#RequestMapping(params = "close", method = RequestMethod.POST)
It doesn't sit well with me that I'm using 'POST' for these calls. Maybe it should be 'PUT'...
Any suggestions? Does it matter?
It depends on what your request should do. So there's no general rule that you should use one over the other, they have different use cases.
POST for creating a record.
PUT for updating an existing record (or putting a record at a specified location/id).
See this wikipedia article for the definitions.
One thing to note is that PUT should be idempotent, doing the same PUT request multiple times should ideally produce the same result as doing a single PUT request. However, POST is not idempotent, so doing several POST requests should (or will) create multiple new records.
So after having read this you should check what your method does, and select the corresponding request method.
Both PUT and POST may create a new record; PUT may also update/change an existing record.
The difference between POST and PUT is that PUT is expected to address the record with it's ID, so that the server knows what ID to use when creating (or updating) the record, while POST expects the server to generate an ID for the record and return it to the client after the record has been created.
Thus, a POST is addressed to the resource as a collection: POST /resource, while PUT is addressed to a single item in the collection: PUT /resource/1
Use POST. Always use POST, unless you're absolutely rock-solid certain that PUT is properly supported by your hosting system.

Resources