AngularJS wrapping JSON data returned from server - javascript

I have a basic CRUD application up and running, however what I am wanting to do is wrap every response from the server with two additonal parameters namely
'error' => boolean, 'errorMessage' => string, 'data' => {whatever data}
so that I can handle when a successful request is sent and returned from the server, however the database was unable to update for some reason so I can not only keep the UI in sync with the DB, but also present the user an error message on a failed update.
As AngularJS expects an updated object the UI will be in sync if I return the same object on failure, but as there would be no notification of failure the user wouldn't realize what the problem is.
Within my old applications pre-Angular (jQuery based) I could easily decode the json data on every response and if error === true present an error message, but in Angular I cannot seem to figure out how to accomplish this.
I may very well be off base here as I am just getting into Angular so any direction would be helpful.

Make this http request from angularjs and send back a response object from server.
response object --->{'error' => boolean, 'errorMessage' => string, 'data' => {whatever data}}
which gets collected in Resdata. use Resdata to take action.
$http({method: 'POST', url:url, data:body}).success(function(Resdata, status, headers, config) {
console.log(Resdata);
if(Resdata.error == true){
// use Resdata.errorMessage
}
else if(Resdata.error == false){
// use Resdata.data
}
}).error(function(Resdata, status, headers, config) {
console.log("error:", error);
});

Related

Ember -- JSON API Adapter Error Handling

I want to take a specific action when an API request results in a 404 error. I've read that the appropriated way to do this would be handling the error in the application adapter like below:
handleResponse: function(status, headers, payload){
if(status === 404 && payload.errors){
//handle error
}
return this._super(...arguments);
}
The problem is, as soon as I set up the adapter, it won't finish loading the page so I can handle the error on the page itself. Instead, it automatically takes me to some error route that just says "Adapter error". How can I stop/override this behaviour?
Turns out I needed to adjust the handleResponse hook in the application adapter to pass the new requestData parameter to the super method.
handleResponse (status, headers, payload, requestData) {
return this._super(status, headers, payload, requestData);
},
Then I just changed the first line of the code in my question from
handleResponse: function(status, headers, payload) {
to
handleResponse: function(status, headers, payload, requestData) {
I was then able to catch and handle the error
Perhaps you could handle it on a request basis like below:
return this.get('store').find('user', userId).then((user) => {
this.set('user', user);
}).catch((reason) => {
var possible404 = reason.errors.filterBy('status','404');
if(possible404.length !== 0) {
// Handle 404 error
}
});
Although this is not the solution that you wanted, this alternative will allow you to customize more. By the way, the automatic behavior seems to be the application-error substates kicking in on 404, so give it a read if you want to override the behavior.

Cannot update Parse object via REST API

Right, so I'm simply trying to update my object via the REST API. My request succeeds, I get a 200 response back containing the latest updated timestamp, but the object's column value has not changed.
My Movies class has a title and a genre column, the rights on the class are set to public read write on all rows.
Here is some code
var data = {title:'The Revenant'};
qwest.put('https://api.parse.com/1/classes/Movies/myObjectId', JSON.stringify(data))
.then(function(xhr, response) {
console.log(response);
})
.catch(function(xhr, response, e) {
console.log(e);
});
The response I get back?
{"updatedAt":"2016-01-24T07:59:54.977Z"}
So the request succeeded but if I GET the object again or check in the Parse admin page, the object has not changed. What gives?
EDIT
FYI, if I use the Javascript SDK, I can update the model.
var Movies = Parse.Object.extend("Movies");
var query = new Parse.Query(Movies);
query.get(myObjectId, {
success: function (movie) {
movie.set("title", data.title);
movie.save();
},
error: function (object, error) {
console.log(error);
}
});
This updates the model. For my particular use case though, I would really prefer to use the REST API rather than the SDK, but I guess this means it is not a permissions issue or an id mismatch etc.,
code snippet
qwest.put('https://api.parse.com/1/classes/Movies/Dh7zjiP9KW', data, {dataType:"json",headers:{'x-parse-application-id':'XXX','X-Parse-REST- API-Key':'XXX'}})
.then(function(xhr, response) {
console.log(response);
})
.catch(function(xhr, response, e) {
console.log(e);
});
The response you're getting indicates that the object was updated successfully. Double check that you're looking at the correct object, and that the "updatedAt" field matches the response you saw earlier.
What happens if you fetch the object right away, using the same "qwest" client and https://api.parse.com/1/classes/Movies/myObjectId resource URL (with the correct object id)?
Try removing JSON.stringify(data) and just pass data,

POST Ajax request by AngularJS to Symfony controller

I'm trying to do an Ajax request from my angularJs controller to my Symfony controller. However, for an unknown reason, I cannot receive the data in my Symfony controller. My controller gets called and I can return some information that I will see in the success function on the AngularJS side. However, the data I'm sending via AngularJs cannot be retrieved on the Symfony controller.
Here's what I'm doing on the AngularJS side:
$http.post('{{ path('admin_ima_processmanagement_project_save', {'id':object.id}) }}',{"projectJson":"test"}).
success(function(data, status, headers, config) {
console.log("yeah");
console.log(data);
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log("oh non");
console.log(data);
});
I can see in my console "yeah" that is appearing after the execution of this request.
In my Symfony controller, I have the following:
$request = $this->container->get('request');
$projectJson = $request->query->get('projectJson');
$response = array("code" => 100, "success" => true, "projectJson" => $projectJson);
return new Response(json_encode($response));
On the console, after the call, I get {"code":100,"success":true,"projectJson":{}} meaning that projectJson is unfortunately empty...
What should I do to retrieve the data that I'm sending from my client ?&
In class Request property query refers to GET parameters.
In your case you need to access to POST parameters, which are in request property.
So your code should look like this:
$projectJson = $request->request->get('projectJson');
More info about Request you will find here.
Symfony2 does not support AngularJS $http data. Because AngularJS sends data as request body, and SF2 reads only $_GET and $_POST.
You have 2 solutions:
Update Php code to handle such data
Update JS code to send classic form data (check https://gist.github.com/bennadel/11212050 for this)

AngularJS: Cancel overwriting values $resource object after calling save ();

var User = $resource(
'http://test/index.php'
);
var user = User.get({id:'1'});
// GET: http://test/index.php?id=1
// server returns: { "login":"foo", "name":"bar", "mail":"baz" }
user.name = "qux";
user.$save();
// POST: http://test/index.php?id=1
// server returns: { "login":"foo", "name":"bar", "mail":"qux"}
In this case, when you call the save() user object, properties will be replaced by those that came from the server.
But if the server responds like this:
{
"errors":{
"login":"too short",
"name":"is already using that name.",
"mail":"invalid email."
}
}
User object properties are overwritten and instead, property errors containing these mistakes will come up.
Is there a way to change the behavior of $resource? I would like to check the status of the response and, based on that, decide whether to update the properties of an object or report an error to the user.
Angular's $resource is meant to interact with RESTful web services.
In RESTful web services, if there's an error while saving a resource, you should return an appropriate HTTP status (for example, 400).
Then, you can optionally use the error callback:
user.$save(function (response) {
console.log("success!");
}, function (response) {
console.log("error");
});
For a full list of error HTTP statuses:
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error

Angular $http error callback response is always undefined

I am having issues trying to gracefully handle $http errors. I am looping over a list of servers to make API calls to for status. The calls that complete successfully for perfectly. The ones that fail are not giving me access to the error information. It is always undefined. Here is the code snippet:
angular.forEach($scope.servers, function (server) {
// blank out results first
server.statusResults = {};
$http.jsonp(server.url + '/api/system/status?callback=JSON_CALLBACK', {headers: { 'APP-API-Key': server.apiKey }}).
success(function (data, status, headers, config) {
server.statusResults = data;
}).
error(function (data, status, headers, config) {
// data is always undefined here when there is an error
console.error('Error fetching feed:', data);
});
}
);
The console output shows the correct 401 error (which I didn't output) and my console error message (which I did output) with an undefined data object.
GET https://server_address/api/system/status?callback=angular.callbacks._1 401 (Unauthorized) angular.min.js:104
Error fetching feed: undefined
What I am trying to do is NOT have Angular display the 401 in the log, and instead I will display it in a graceful way. However since data is undefined I have no way of accessing the information.
I am new to AngularJS, but my example closely matches other examples I've found in the documentation.
I've also tried using $resource instead of the $http and got the exact same problem.
var statusResource = $resource(server.url + '/api/system/status', {alt: 'json', callback: 'JSON_CALLBACK'},
{ status: {method: 'JSONP'}, isArray: false, headers: { 'APP-API-Key': server.apiKey } });
// make status API call
statusResource.status({}, function (data) {
server.statusResults = data;
}, function (err) {
// data is always undefined here when there is an error
console.log(err);
});
I'm probably doing something obviously wrong, but I'm not sure what else to try.
Per the $http docs, body is
The response body transformed with the transform functions.
With the 401 (Unauthorized) error you are getting back, it is quite possible there is no body being returned, hence why it is undefined.
If you want to log the error code, log the status parameter instead. It contains the HTTP Status Code, which should be uniform, unlike response bodies.

Categories