Turn request success into error based on response data - angularjs

I am relatively new to Angular js and trying to use promises along with services and got reference http://plnkr.co/edit/b4HPbX2olM745EfHVcc6?p=preview. But in my application I am getting response as {"Response":"exception while loading Reports List","error":"Exception getting all records.","status":"failure"}. When I get response like this, I need to show an alert message with the message in "error" (i.e., Exception getting all records) and set $scope.data to [] in my controller.What are the changes I need to make to services and controller to handle this. Any help is much appreciated.
In services :
return $q.when(originalRequest)
.then(function(res) {
data = res.ResultSet.Response;
return data;
});
In Controller,
DashboardsDataService.getNetSpendOverTimeData()
.then(function(data) {
$scope.data = data;
});
The following is my original request to Java action class:
var originalRequest = $.ajax({
async : false,
url : "/dash2/dashd2ajax.do",
type : "POST",
data : {
action : 'getNetSpendOverTime',
customerId : selectedAccTd,
carriersId : selectedCarriers,
fromDate : fromDate,
toDate : toDate,
modes : selectedModes,
services : selectedServices,
dateType : selectedDateType,
lanesList : selectedLaneList
},
dataType : "json"
});
return $q.when(originalRequest)
.then(function(res) {
data = res.ResultSet.Response;
return data;
});

If what you're asking is "how do I turn request success into a failure based on result data", then take a look at the following example:
return $q.when(originalRequest).then(function (res) {
if (res.ResultSet.error) {
return $q.reject(res.ResultSet.error);
} else {
return res.ResultSet.Response;
}
});
Using $q.reject() turned your data into a real "promise failure", so in your controller, you can use the normal promise API:
doSomethingAsynchronous().then(function (data) {
$scope.data = data;
}, function (error) {
$scope.data = [];
alert(error);
});

Related

Custom error message with content-type response

I'm trying to implement some error handling into my MCV AngularJS application, but came across this one issue that I'm not sure how to solve.
Structure
In my AngularJS service ticketService I have the following method:
this.downloadFile = function (fileId) {
return $http.get(baseUrl + "/Downloadfile/" + fileId, { responseType: "blob" });
}
And in my controller:
$scope.downloadFile = function (fileId) {
ticketService.downloadFile(fileId)
.then(function (response) {
// Handle correct request and response
}, function (err) {
// Handle error
notify({ message: "Something went wrong: " + err.data.Message, position: "center", duration: 10000 });
})
}
Here's what I return from the backend MVC Web API method:
var error = new HttpError("Failed to find file, bla bla bla.");
return Request.CreateResponse(HttpStatusCode.NotFound, error);
Problem
My issue is that since my responseType is set to be blob, my err object is the same response type. I would believe that it should be possible for my backend service to override this response type, and respond with an object that contains some Message.
From this response, I would've thought that I could get err.data.Message, but perhaps I misunderstood this scenario?
Thank you in advance.
public HttpResponseMessage Get(int id)
{
try
{
return Request.CreateResponse(HttpStatusCode.OK, new { Status =
"OK", Message = this._myContext.GetCustomer(id) });
}
catch(Exception e)
{
return Request.CreateResponse(HttpStatusCode.Conflict, new {
Status = "NO", Message = e.ToString() });
}
}
You can return any message like "Failed to find file, bla bla bla." in Message. Then you just need to check in ajax success method like data.Message,
The $http service uses the XHR API which is not capable of changing the responseType on the fly.
You can set the status message and use that:
public ActionResult Foo()
{
Response.StatusCode = 403;
Response.StatusDescription = "Some custom message";
return View(); // or Content(), Json(), etc
}
Then in AngularJS:
$scope.downloadFile = function (fileId) {
return ticketService.downloadFile(fileId)
.then(function (response) {
// Handle correct request and response
return response.data;
}).catch(function (response) {
// Handle error
console.log(response.status);
console.log(response.statusText);
throw response;
});
};
Alternative approaches are:
Use the Fetch API which has a more powerful and flexible feature set.
Use the FileReader API and JSONparse() method to convert the Blob to a JavaScript Object.

unable to display the http get response from the factory in controller in Angularjs application

In my service I making http get request as shown below:
.factory('InvoicesGeneralService', function ($http) {
return {
getAgreementsByCourierId: function (courierId) {
console.log("Courier in Services" + courierId);
return $http.get('/api/agreements/byCourierId', {params: {courierId: courierId}}).then(function (response) {
return response;
});
}
};
});
And in browser console I am seeing the following response :
[
{
"id":3,
"number":"AGR53786",
"ediNumber":"EDI7365",
"startDate":"2012-09-02",
"endDate":"2018-07-01",
"courier":{
"id":2,
"name":"FedEx",
"url":"www.fedex.com",
"isActive":true,
"isParcel":true
},
"client":{
"id":4,
"code":"KJGTR",
"name":"Hearty",
"isActive":true,
"engageDate":"2011-07-07",
"isSendRemittance":true,
"upsUserName":"Tkd",
"upsPassword":"kuu",
"isEligibleForTracking":true,
"isEligibleForAuditing":true,
"status":5
}
}
]
And in my controller I am assigning it to result List :
$scope.resultList = InvoicesGeneralService.getAgreementsByCourierId(selCourierId);
But my resultList is always appearing as Empty. Can any one help me, why it is happening?
When I am trying to display resultList as shown below, it always shows empty object, {}. It supposed to display the response json array from the service but it is showing empty object.
<pre class="code"> {{resultList | json}}</pre>
$http returns a promise. Anything consuming that data needs to handle it like a promise too.
InvoicesGeneralService.getAgreementsByCourierId(selCourierId).then(function(data) {
$scope.resultList = data;
});
Also, your factory's then function is not doing anything at the moment. You should return the response's data from it.
return $http.get('/api/agreements/byCourierId', {params: {courierId: courierId}}).then(function (response) {
return response.data;
});

How to make a REST request in my case?

I am reading a RESTFUL API doc and one of the PUT methods requires request body to be sent.
The doc mentions
PUT /api/v1.2/product/{id}
with request body like
{
"name" : "Toy",
"description" : "Kids toy",
"price" : 25
}
my current request codes.
$http.put('/api/v1.2/product/' + ID);
I am trying to use Angular http request to make the call but not sure how to make the request with the request body. Can someone help me about it? Thanks a lot!
The data goes in the second parameter to put. For example:
var data = {
"name" : "Toy",
"description" : "Kids toy",
"price" : 25
};
$http.put('/api/v1.2/product/' + ID, data)
.success(function(response, status, headers, config){
//do something with response here.
})
.error(function(response, status, headers, config){
//handle error here.
$scope.error_message = response.error_message;
});
For more info, see here
The angular defines some syntax, you have to main that other wise you won't do anything. You can try is
JS CODE
var data = {
"name" : "Toy",
"description" : "Kids toy",
"price" : 25
};
$scope.save = function () {
$http.put('/api/v1.2/product/' + ID, data).success(function (data) {
}).error(function (data) {
$scope.error = "An Error has occured while Saving customer! " + data;
$scope.loading = false;
});
};
API CODE
public HttpResponseMessage Put(int ID, Product product)
{
}
I have written a article into code project here. From here you can get full concept of $http get , put, delete.
$resource possibly provides a nicer api (though still uses $http under the hood)
Given your data:
var data = {
"name" : "Toy",
"description" : "Kids toy",
"price" : 25
};
Setup your resource
var Product = $resource('/api/v1.2/product/:id', { 'put': { method:'PUT' } });
Then to make a request with it, you just need to:
Product.put({ id: ID }, data);
If you want to handle a response or errors, just pass the callbacks in too:
Product.put({ id: ID }, data, function(data){ }, function(error){ });
Check out the documentation: https://docs.angularjs.org/api/ngResource
It can do some pretty cool stuff with promises (Not that $http can't, $resource is just a little nicer IMHO)
It provides GET, POST and DELETE methods by default. PUT is a special case so thats why we needed to specify it above.

Angularjs issue in relacing Ajax request with promises in service

For my Angularjs application in services I have used Ajax call to get the data and is as follows :
var originalRequest = $.ajax({
async : false,
url : "/dash/dashboard2ajax.do",
type : "POST",
data : {
action : 'getNetSpendOverTime',
customerId : selectedAccTd,
carriersId : selectedCarriers,
fromDate : formattedFromDate,
toDate : formattedToDate
},
dataType : "json",
success : function(originalRequest) {
var res = originalRequest;
data = res.ResultSet.Response;
}
});
Then I just return (data) from my service and in my controller I am able to get data without any problem. But I realized it is a bad practice and trying to use promises. So I have replaced it as follows:
var originalRequest = $http({
url: "/dash/dashboard2ajax.do",
method: "POST",
data: {action : 'getNetSpendOverTime',
customerId : selectedAccTd,
carriersId : selectedCarriers,
fromDate : formattedFromDate,
toDate : formattedToDate}
}).success(function(data, status, headers, config) {
return (data);
}).error(function(data, status, headers, config) {
return(status);
});
But it is not working. None of the parameters are getting even passed to my action class. Is there any mistake in my syntax?
In my action class, I am accessing the parameters as
String action = request.getParameter("action");
But it is coming as null.
You're trying to replace jQuery.ajax with AngularJS $http, which has completely different contract. The thing you're calling originalRequest is not in fact any kind of "request object". It's just a Promise (extended with success and error methods). If you want to access the request data outside your success/error handlers, you need to save and pass it separately yourself:
var data = {
// ...
};
var request = $http({
data: data,
// ...
});
return {
request: request,
data: data
};
If you need to access it inside the handlers, just get it from the config argument:
$http(...).success(function (data, status, headers, config) {
var action = config.data.action;
// ...
});

Jquery-Ajax call not working as expected

i'm working on a project like this:
(HTML Forms(AJAX)+ twitter bootstrap)(solo HTML, no JSP,etc..)->Servlets(on Google App Engine-JAVA)->Persistence(Google Cloud SQL).
I'm quite new to jQuery ajax calls, but i understand the process, as i'm used to write the old XHR code.
Below is the function in JS, that does not write to console the expected result..so far most of the times form data is persisted.
My Servlet if fine, and outputs a valid JSON.(calling the URL on a browser always works as expected.)
My answer is why jQuery ajax callbacks(done,fail,always) aren't working properly? They do write to console/display alert().
THANKS, for your time!
$(document).ready(function() {
var myEmail = "";
var myGender = "";
$('#saveButton').click(function() {
$('#myform').submit();
//alert('Handler for .submit() called.');
myEmail = document.getElementById("inputEmail").value;
window.console.log('EMAIL---->' + myEmail);/*ok log!*/
//alert('EMAIL->' + myEmail);
var radioObj = document.forms['myForm'].elements['gender'];
myGender = getCheckedValue(radioObj);
window.console.log('GENDER---->' + myGender);/*ok log!*/
//alert('GENDER->' + myGender);
var jqXHR = $.ajax({
statusCode : {
404 : function() {
alert("404 ERROR - page not found");
}
},
url : "/newuser",
type : "GET",
timeout : 10000,
data : {
email : myEmail,
gender : myGender,
operation : '0'
},
done : function(data, textStatus, jqXHR) {
window.console.log('done -> RESPONSE---->' + data);/*this does not log!*/
alert(data);
},
fail : function(jqXHR, textStatus, errorThrown) {
window.console.log('always -> RESPONSE---->' + data); /*this does not log!*/
alert(data);
},
always : function(data, textStatus, jqXHR) {
window.console.log('always -> RESPONSE---->' + data); /*this does not log!*/
alert(data);
}
});
});
});
done, fail and always are not properties of the settings object passed to $.ajax, they are callbacks on the jqxhr object returned by the call to $.ajax. They should be configured like this instead:
var jqxhr = $.ajax( "example.php" )
.done(function() { alert("success"); })
.fail(function() { alert("error"); })
.always(function() { alert("complete"); });
Check out the API documentation for further usage guidance.

Resources