Angularjs issue in relacing Ajax request with promises in service - angularjs

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;
// ...
});

Related

AngularJS what is difference between $http success and then

various people use $http different way. say sample 1
$http({
method: 'GET',
url: 'api/book/',
cache: $templateCache
}).
success(function (data, status, headers, config) {
$scope.books = data;
}).
error(function (data, status) {
console.log("Request Failed");
});
here success and error callback is there to notify user. again few people use $http different way like
this.getMovie = function(movie) {
return $http.get('/api/v1/movies/' + movie)
.then(
function (response) {
return {
title: response.data.title,
cost: response.data.price
});
},
function (httpError) {
// translate the error
throw httpError.status + " : " +
httpError.data;
});
};
here then is using.......is it promise sample ? why people would then instead of success ? what is the advantage of then ?
what is the meaning of promise and what promise does ?
when to use promise in angular ?
Per angular DOCS, looks like 1.4.4 is the first version to have the notice(see below).
Deprecation Notice
The $http legacy promise methods success and error have been
deprecated. Use the standard then method instead. If
$httpProvider.useLegacyPromiseExtensions is set to false then these
methods will throw $http/legacy error.
From the docs, the new preferred angular way to do all $http requests.(code from angular docs)
General usage
The $http service is a
function which takes a single argument— a configuration object— that is used to generate an HTTP request and returns a promise.
// Simple GET request example :
$http.get('/someUrl').
then(function(response) {
// this callback will be called asynchronously
// when the response is available
}, function(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
// Simple POST request example (passing data) :
$http.post('/someUrl', {
msg: 'hello word!'
}).
then(function(response) {
// this callback will be called asynchronously
// when the response is available
}, function(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
SO resource
SO resource

ExpressJS IP and AngularJS $http get

I'm trying to learn ExpressJS and I'm having trouble getting IP address from an Express route to display in the browser via Angular controller.
I'm using 2 Nodejs modules (request-ip and geoip2) to get the IP and then lookup geolocation data for that IP. Then trying to use Angular to display the geolocation data in the browser using an Angular $http get call.
My Express route for the IP:
// get IP address
router.get('/ip', function (req, res, next) {
console.log('requestIP is ' + ip);
// geolocation
geoip2.lookupSimple(ip, function(error, result) {
if (error) {
//return res.status(400).json({error: 'Something happened'});//default
return res.sendStatus(400).json({error: 'Something happened'});
}
else if (result) {
return res.send(result);
}
});
});
And my AngularJS controller code:
function MainController($http) {
var vm = this;
vm.message = 'Hello World';
vm.location = '';
vm.getLocation = function() {
$http({
method: 'GET',
url: 'localhost:8000/ip'
}).then(function (result) {
console.log(result);
return vm.location = result;
});
};
};
The Hello World message displays but not the location...? I can also go to localhost:8000/ip and see the JSON result. The result doesn't appear in Chrome's console either. The result is a json object like this:
{"country":"US","continent":"NA","postal":"98296","city":"Snohomish","location":{"accuracy_radius":20,"latitude":47.8519,"longitude":-122.0921,"metro_code":819,"time_zone":"America/Los_Angeles"},"subdivision":"WA"}
I'm not sure why the Hello Word displays and the location doesn't when it seems that I have everything configured correctly... so obviously I'm doing something wrong that I don't see...?
You have initialised 'vm.location' as a string when in fact it is a JSON object.
vm.location = {};
You need to adjust the url paramater in your request to:
url: '/ip'
As you are sending back JSON from Express.js, you should change your response line to:
return res.json(result);
Do you call vm.getLocation() somewhere in your code after this?
The data you need is under result.data from the response object.
Also in order to display the data in the html you have to specify which property to display from the vm.location object (vm.location.country, vm.location.city etc..).
From angular docs about $http:
The response object has these properties:
data – {string|Object} – The response body transformed with the transform functions.
status – {number} – HTTP status code of the response.
headers – {function([headerName])} – Header getter function.
config – {Object} – The configuration object that was used to generate the request.
statusText – {string} – HTTP status text of the response.
Is this express js and angular hosted on the same port? If so please replace your
$http({
method: 'GET',
url: 'localhost:8000/ip'
}).then(function (result) {
console.log(result);
return vm.location = result;
});
with
$http({
method: 'GET',
url: '/ip'
}).then(function (result) {
console.log(result);
return vm.location = result;
});
It may be considered as CORS call and you have it probably disabled.
You can also specify second function to then (look code below) and see if error callback is called.
$http({
method: 'GET',
url: '/ip'
}).then(function (result) {
console.log(result);
return vm.location = result;
}, function (error) {
console.log(error);
});

Angularjs - 500 (Internal Server Error) on $http Post

I am new to Ionic and angular. I am building a sample with ionic framework using angular.js. I want to call WebApi through $http post method. I checked this(ionic-proxy-example) solution and I am trying to implement the same using my api. When I call the api provided in above example in my sample project, I get the records but its not working with my api. It throws 500 internal error.
Here is my app.js
angular.module('myApp', ['myApp.controllers', 'myApp.services'])
.constant('ApiEndpoint', {url: 'http://localhost:8100/api'})
Services.js
angular.module('myApp.services', [])
.factory('Api', function($http, $q, ApiEndpoint) {
console.log('ApiEndpoint', ApiEndpoint)
var getApiData = function() {
var q = $q.defer();
var data = {
Gameweek_ID: '179',
Vender_ID: '1',
Language:'en'
};
var config = {
headers : {
"Content-Type": "application/json; charset = utf-8;"
}
};
$http.post(ApiEndpoint.url, data, config)
.success(function (data, status, headers, config) {
// $scope.PostDataResponse = data;
alert('success');
console.debug("response :" + data);
q.resolve(data);
})
.error(function (data, status, header, config) {
// $scope.ResponseDetails = "Data: " + data +
alert('error');
console.debug("error :" + data);
q.reject(data);
});
return q.promise;
}
return {getApiData: getApiData};
})
controllers.js
angular.module('myApp.controllers', [])
.controller('Hello', function($scope, Api) {
$scope.employees = null;
Api.getApiData()
.then(function(result)
{console.log("result is here");
jsonresponse = result.data;
$scope.employees = jsonresponse;}
)
});
And Ionic.Project File
{
"name": "Multilingual",
"app_id": "4b076e44",
"proxies": [
{
"path": "/api",
"proxyUrl": ""
}
]}
I am trying to understand the problem and checked multiple methods to call the api. Surprisingly, it works with ajax post call without any CORS errors. As I am using Angular, I am trying to get this done through $http post. I feel it is some minor issue but I am not able to figure out. Will be grateful for solutions. Thank you.
You've set the content type to json so the sever is expecting a json string but isn't receiving a properly formatted json string as you're sending through an object and hence the error.
Where you have $http.post(ApiEndpoint.url, data, config) change it to $http.post(ApiEndpoint.url, JSON.stringify(data), config).
If that doesn't work, change your content type to application/x-www-form-urlencoded and update this line $http.post(ApiEndpoint.url, data, config) to $http.post(ApiEndpoint.url, $httpParamSerializer(data), config) , don't forget to inject the $httpParamSerializer function.
The problem is that you are sending a POST with $http.post request instead of a GET request with $http.get
Try as below-
$http({
url: ApiEndpoint.url,
method: "POST",
data: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).Success(..rest code goes here..)
In WebAPI, when we pass more than one object in POST method, we get 500 internal error and hence we use ViewModel in such scenarios(talking about asp.net MVC).

Turn request success into error based on response data

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);
});

AngularJS $http ajax request is not asynchronous and causes page to hang

I have a service where I am pulling data from server. When I click the button to send out the request to server through this service, the window freezes until I receive a response from server. Is there anything I can do to make this request asynchronous ?
Here is my service.
app.factory('service', function($http) {
return {
getLogData : function(startTime,endTime){
return $http({
url: baseURL + 'getLogData',
method: 'GET',
async: true,
cache: false,
headers: {'Accept': 'application/json', 'Pragma': 'no-cache'},
params: {'startTime': startTime , 'endTime': endTime}
});
}
};
)};
HTML.
<button ng-click="getData()">Refresh</button>
<img src="pending.gif" ng-show="dataPending" />
Code
$scope.getData = function(){
service.getLogData().success(function(data){
//process data
}).error(function(e){
//show error message
});
}
While there is some argument about the pros and cons of your approach, I am thinking that the problem is answered here: AJAX call freezes browser for a bit while it gets response and executes success
To test if this in fact part of the problem, dummy up a response and serve it statically. I use Fiddler or WireShark to get the response and then save to a file like testService.json. XHR and all of it's various derivatives like $HTTP $.ajax see it as a service though the headers might be slightly different.
Use the success promise, and wrap up the log data in a set of objects that you can attach to a $scope.
So instead of having your service have a blocking method, have it maintain a list of "LogEntries".
// constructor function
var LogEntry = function() {
/*...*/
}
var logEntries = [];
// Non-blocking fetch log data
var getLogData = function() {
return $http({
url : baseURL + 'getLogData',
method : 'GET',
async : true,
cache : false,
headers : { 'Accept' : 'application/json' , 'Pragma':'no-cache'},
params : {'startTime' : startTime , 'endTime' : endTime}
}).success(function(data) {;
// for each log entry in data, populate logEntries
// push(new LogEntry( stuff from data ))...
};
}
Then in your controller, inject your service and reference this service's log data array so Angular will watch it and change the view correctly
$scope.logEntries = mySvc.logEntries;
Then in the HTML, simply do something over logEntries:
<p ng-repeat="logEntry in logEntries">
{{logEntry}}
</p>
use this code to config
$httpProvider.useApplyAsync(true);
var url = //Your URL;
var config = {
async:true
};
var promise= $http.get(url, config);
promise.then(
function (result)
{
return result.data;
},
function (error)
{
return error;
}
);

Resources