http.post always entering error callback in IE8 - javascript

I have a simple Angular service that works fine in FireFox, Safari, Chrome and IE9+
However, for IE8, the service is always hitting the .error callback.
JS:
myService.authUser($scope.data)
.success(function(data, status, headers, config) {
console.log("Success..");
$scope.showProfile = true;
})
.error(function (data, status, headers, config) {
console.log("ERRROR!!!");
$scope.errorText = true;
})
app.service('myService', function($http) {
this.authUser = function (myData) {
return $http({
url: 'url',
method: "POST",
data: angular.toJson(myData),
headers: {
'Content-Type': 'application/json'
}
});
};
});
In the above scenario, IE8 is always logging ERRROR!!!

Make sure that the url you are hitting responds with the correct status code EG : 200, 404 etc
For example if your backend is .NET MVC
public ActionResult TestError(string id) // id = error code{
Response.StatusCode = 400; // Replace .AddHeader
var error = new Error(); // Create class Error() w/ prop
error.ErrorID = 123;
error.Level = 2;
error.Message = "You broke the Internet!";
return Json(error, JsonRequestBehavior.AllowGet);}

Related

angularjs$http.get and java api call

I'm trying to make an angularjs $http.get request with parameters but it's not working due to syntaxt may be. Can you please
confirm what i'm doing wrong , maybe syntax is wrong in angularjs call or in java api method
$http.get(document.requestPathPrefix + "/home/my-api",
$scope.requestParametersObject
).then(
function(response) {
$scope.output = response.data;
},
function(response) {
$scope.retrieveErrorMssg = "Failed to retrieve required data.";
});
my parameters are like in this image
parameter object for api call
And in java api call like this
#RequestMapping(value = "/my-api", method = RequestMethod.GET)
public ResponseEntity<Collection<MyObjectResponse>> getMyObjResponse(#RequestBody final MyObjectRequest request)
{
Map<Integer,MyObjectResponse> oResponse = new HashMap<>();
try {
//Manipulation and db calls
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return new ResponseEntity<Collection<MyObjectResponse>>(oResponse.values(), HttpStatus.OK);
}
try ,
$http({
url: '/home/my-api',
method: "GET",
headers: {
'Content-type': 'application/json'
},
data: JSON.stringify(request)
}).success(function(data, status, headers, config) {
}).error(function(data, status, headers, config) {
return null;
});
If you are worried about syntax, take a look at this simple example and modify it to your need.
In JS, your http.get call should contain the URL and its parameters if any,
$http.get('getUserInfo',
{
params : {
'userEmail' : 'userEmail'
}
}).then(function(response) {
console.log(response);
});
If you are passing a parameter to the API call, ensure your Java controller or the service has the parameter defined to receive the same. Ideally the parameters should match between the call and the provider
For example, for the above API call, the spring controller should like below,
#RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
public #ResponseBody User getUserInfo(
#RequestParam("userEmail") String userEmail) {
// Do Something
}

Loader not being shown on ajax request in angular js

Since I am using ajax request using $http. It takes a long time since my operation on server takes time. I need to show loader while processing request, but the loader does not show. Although my code seems correct. I tried different methods but did not work.
Index.html
<body ng-app="app">
<!-- loader, can be used on multiple pages-->
<div class="loading loader-quart" ng-show="isLoading"></div>
<!-- my logic -->
</body>
addCtrl.js
//method to get all the attributes and send to server using service
$scope.add = function () {
if ($scope.Option == 'newInstance')
$scope.singleObject.FK_Name = 'MetisEmptyTemplate';
$rootScope.isLoading = true;
var featuresList = websiteService.getUpdatedTree($scope.treeDataSource);
var formData = new Website("", $scope.singleObject.Name, $scope.singleObject.DisplayName, $scope.singleObject.Description, $scope.singleObject.State, "", $scope.singleObject.FK_Name, $scope.singleObject.Email, featuresList);
websiteService.addwebsite(formData);
$rootScope.isLoading = false;
}
websiteService.js
//service to add website
this.addwebsite = function (website) {
$http({
method: 'POST',
url: $rootScope.url + 'Add',
data: JSON.stringify(website),
contentType: 'application/json'
}).success(function (data) {
alert(data);
}).error(function (data, status, headers, config) {
//alert(data);
});
}
Since I am going to turn isLoading as "true" in start and then after request completes I turn isLoading "false". Where is the problem in code?
Your websiteServices code gets executed asynchronously. Which means that the above code would display the loader and then pretty much hide it again instantly.
To handle async code in the controller you must return a promise from the service and put the hiding of the spinner in a callback function using .then().
service:
this.addwebsite = function (website) {
var deferred = $q.defer();
$http({
method: 'POST',
url: $rootScope.url + 'Add',
data: JSON.stringify(website),
contentType: 'application/json'
}).success(function (data) {
alert(data);
deferred.resolve(data);
}).error(function (data, status, headers, config) {
//alert(data);
deferred.reject(data);
});
return deferred.promise
}
controller:
websiteService.addwebsite(formData).then(function(){
$rootScope.isLoading = false
});
this.insertMliveResponse = function(data){
var defer=$q.defer();
var requestURL='/mlive-portlet/rest/mliveResponseService/insertmLiveResponse';
httpRequest(requestURL,data).then(function(data){
defer.resolve(data.data);
},function(data){
defer.reject(data.data);
})
return defer.promise;
}
If you are making request then,
I think the best way to show hide loader is interceptor
In my snippet, I am using loader service to activate/deactivate loader
For Eg:
// http.config.js file
export function httpConfig($httpProvider, AuthInterceptProvider) {
'ngInject';
AuthInterceptProvider.interceptAuth(true);
// added for show loader
$httpProvider.interceptors.push(function (loaderService, $q) {
'ngInject';
return {
'request': function (config) {
loaderService.switchLoaderModeOn();
return config;
},
'requestError': function (rejection) {
loaderService.switchLoaderModeOff();
return $q.reject(rejection);
},
'response': function (response) {
loaderService.switchLoaderModeOff();
return response;
},
'responseError': function (rejection) {
loaderService.switchLoaderModeOff();
return $q.reject(rejection);
}
};
});
}
// and in your module.js file
import {httpConfig} from './config/http.config';
.config(httpConfig)

Angularjs $http.post - sending params as JSON to ASPX webmethod

I have the following angularjs code sending http post to a webmethod, but I get the following error with no more info. Can someone help?
If I do not send any data to webmethod and only get data from it, it works just fine !
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
angular.js:11442 POST http://localhost:54461/GetData.aspx/getData 500 (Internal Server Error)
Javascript:
var request = "{'name':'" + "Nariman" + "'age':'" + 12 + "'}";
$scope.retData = {};
var config = {
headers: {
'Content-Type': '"application/json; charset=utf-8";',
'dataType': '"json"'
}
}
$scope.retData.getResult = function (item, event) {
$http.post('GetData.aspx/getData', request, config)
.success(function (data, status, headers, config) {
$scope.retData.result = data.d;
})
.error(function (data, status, headers, config) {
$scope.status = status;
});
}
ASPX webmethod (C#):
public static string getData(string name, int age)
{
string.Format("Name: {0}{2}Age: {1}", name, age, Environment.NewLine);
}
EDIT --------------------------------------
If I do not send any json data to the webmethod, it works just fine. for example the below code works and if I put break point inside the webmethod, it shows that it goes there. but if I send json data, it does not go inside webmethod:
Javaacript (not sending any json data):
var config = {
headers: {
'Content-Type': '"application/json; charset=utf-8";',
'dataType': '"json"'
}
}
$scope.retData.getResult = function(item, event) {
$http.post('GetData.aspx/getData', data, config)
.success(function(data, status, headers, config) {
$scope.retData.result = data.d;
})
.error(function(data, status, headers, config) {
$scope.status = status;
});
}
ASPX (When no input param)
public static string getData()
{
// just having a breakpoint shows it comes inside the
// webmethod when no data is passed.
}
your issue seems to be as pointed by Emmanual Durai in first comment of your question: var request = "{'name':'" + "Nariman" + "'age':'" + 12 + "'}"; is not a valid json object.
request will give you {'name':'Nariman'age':'12'} as String which won't parse to JSON (there are issues with format).
You should try something like below to get a valid string
var request = {
name: "Nariman",
age: 12
}
var requestString = JSON.stringify(request)
also please have a look here How to pass json POST data to Web API method as object. your issue is not typically specific to angularjs $http but in general to XHR request.
Simply change:
var request = "{'name':'" + "Nariman" + "'age':'" + 12 + "'}";
To:
var request = { name: "Nariman", age: 12 };
You don't have to use JSON.stringify()
var request = { name: "Nariman", age: 12 };
var config = {
headers: {
"Content-Type": "application/json; charset=utf-8"
}
}
$http.post('GetData.aspx/getData', request, config)
.success(function(data, status, headers, config) {
$scope.retData.result = data.d;
})
.error(function(data, status, headers, config) {
$scope.status = status;
});

AngularJS $resource in service function

I'm working in a team that is building an Android application using web technologies (angular.js, etc.) and Phonegap to turn the project into an Android application. We're fairly new to AngularJS and have run into a problem integrating services into our code. We are trying to do some basic server calls, which are working as regular code, but we are trying to make them a service so we don't duplicate this all over the place. We're using a Phonegap localStorage plugin to store the ID of a database object on the phone's HTML5 local storage.
Here is our code:
.service("contactServer", function($resource, $http, baseUrl) {
// Initialize resource and modify methods s.t. create POSTS and save PUTS.
this.post = function() {
alert("Starting post");
var item = {"name": model.userName, "position": model.position};
alert("Creating resource");
var serverResource = $resource(baseUrl,
{create: {method: "POST"}, save: {method: "PUT"}});
alert("Created resource");
new serverResource.create(item).then(function(data, status, headers, config) {
alert("id: " + data._id);
window.localStorage.setItem("DBid", data._id);
}, function(data, status, headers, config) {
alert(JSON.stringify(['Error', data, status, headers, config]))
})
}
this.put = function() {
alert("Starting put");
var item = {"name": model.userName, "position": model.position, "id": window.localStorage.getItem("DBid")};
alert("Creating resource");
var serverResource = $resource(baseUrl + "/:id", {id: "#id"},
{create: {method: "POST"}, save: {method: "PUT"}});
alert("Created resource");
new serverResource(item).save().then(function(data, status, headers, config) {
alert(JSON.stringify(['Success', data, status, headers, config]));
}, function(data, status, headers, config) {
alert(JSON.stringify(['Error', data, status, headers, config]));
})
}
})
baseUrl is a URL link to our database. We call the services here:
.run(function(contactServer) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
if (window.localStorage.getItem("DBid") == null) {
alert("no DBid");
contactServer.post();
}
else {
alert("Retrieved stored DBid: " + window.localStorage.getItem("DBid"));
contactServer.put();
}
}
})
deviceready is a Phonegap event that fires when the application has loaded on the user's phone. We want to call these services in several of our controllers, but also initially during this run function.
The code fires up to the "starting post" alert after being called in the run function, but then breaks. Are we using $resource wrong? (It is correctly listed as a dependency). Are we implementing the service wrong?
The problem you have is the definition of your method
change this
var serverResource = $resource(baseUrl,
{create: {method: "POST"}, save: {method: "PUT"}});
Into this:
var serverResource = $resource(baseUrl, {},
{create: {method: "POST"}, save: {method: "PUT"}});
Take a look at the documentation
So as yours methods are non Get instances you should execute them like following:
new serverResource.$create(item).then(function(data, status, headers, config) {
//content
}, function(data, status, headers, config) {
//error content
})
The documentation says:
HTTP GET "class" actions: Resource.action([parameters], [success], [error])
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
non-GET instance actions: instance.$action([parameters], [success], [error])
I would encourage you to use console.log instead of alerts to debug your code, the alert could create some problems with the digest cycle.
Let me give you an alternative solution:
.factory('contactServer', ['$resource', function($resource){
var baseUrl = 'testing/:id';
var resource = $resource(baseUrl, {id: '#id'}, {update: {method: 'PUT'}});
return resource;
}]);
and you would use it as:
.run(function(contactServer) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
if (window.localStorage.getItem("DBid") == null) {
alert("no DBid");
//item creation
var instance = new contactServer(item);
contactServer.$save(item).then(function(res){
window.localStorage.setItem("DBid", res._id);
});
}
else {
alert("Retrieved stored DBid: " + window.localStorage.getItem("DBid"));
var id = //theId;
var updateObject = //item update;
var instance = new contactServer();
contactServer.$update({id: id}, updateObject).then(function(res){
console.log('object updated!');
});
}
}
});
..or something like that. Hope this help.
Hope this helps you on the right way:
var app = angular.module("app", ["ngResource"]);
app.service("contactServer", function($resource, $http) {
// Initialize resource and modify methods s.t. create POSTS and save PUTS.
var baseUrl = "test";
var model = {
userName: "",
position: ""
}
var serverResource = $resource(baseUrl + "/:id", {id: "#id"},
{create: {method: "POST"}, save: {method: "PUT"}});
this.post = function() {
alert("Starting post");
var item = {"name": model.userName, "position": model.position};
serverResource.create(item).then(function(data, status, headers, config) {
alert("id: " + data._id);
window.localStorage.setItem("DBid", data._id);
}, function(data, status, headers, config) {
alert(JSON.stringify(['Error', data, status, headers, config]))
})
}
this.put = function() {
alert("Starting put");
var item = {"name": model.userName, "position": model.position, "id": window.localStorage.getItem("DBid")};
serverResource.save(item).then(function(data, status, headers, config) {
alert(JSON.stringify(['Success', data, status, headers, config]));
}, function(data, status, headers, config) {
alert(JSON.stringify(['Error', data, status, headers, config]));
})
}
});
app.run(function(contactServer) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
if (window.localStorage.getItem("DBid") == null) {
alert("no DBid");
contactServer.post();
}
else {
alert("Retrieved stored DBid: " + window.localStorage.getItem("DBid"));
contactServer.put();
}
}
});
To make it a bit better I would return serverResource object from the service contactServer and use the resource's save and create methods in the controllers and run block (also resolve promises there).
In short: you have to create the $resource only once with $resource() (outside service function declarations) and just use that in the functions. Also no need for new keyword, might be the thing that breaks this.
Don't you need to change
serverResource.create(item).then(function(data, status, headers, config) {...}
into
serverResource.create(item).$promise.then(function(data, status, headers, config) {...}
--------
see https://docs.angularjs.org/api/ngResource/service/$resource
at the end of the "Credit card resource" example
Actually it's interesting question.
As workaround I would suggest you to use Restangular if you want to build reusable instance for making http queries. In this case it has some advantages:
- It uses promise instead of returning empty object and filling it with new data. (it's actually behaviour of ngResource). Thus you can reuse your services in resolve sections.
- You don't have to create one $resource object per request.
- Support a lot of http methods.
Here is example:
angular.module('app').service('accountService'function(Restangular){
var baseAccounts = Restangular.all('accounts');
this.getAll = function(){
return baseAccounts.getList();
}
this.getById = function(id){
/accounts/profile/{id}
return baseAccounts.one('profile',id)
}
})
More information you can find here. https://github.com/mgonto/restangular#differences-with-resource

Sending JSON using $http cause angular to send text/plain content type

I just want to send the following JSONobjects to my API backend:
{
"username":"alex",
"password":"password"
}
So I wrote the following function, using Angular $http:
$http(
{
method: 'POST',
url: '/api/user/auth/',
data: '{"username":"alex", "password":"alex"}',
})
.success(function(data, status, headers, config) {
// Do Stuff
})
.error(function(data, status, headers, config) {
// Do Stuff
});
I read in documentation for POST method that Content-Type header will be automatically set to "application/json".
But I realized that the content-type I receive on my backend (Django+Tastypie) api is "text/plain".
This cause my API to not respond properly to this request. How should I manage this content-type?
The solution I've moved forward with is to always initialize models on the $scope to an empty block {} on each controller. This guarantees that if no data is bound to that model then you will still have an empty block to pass to your $http.put or $http.post method.
myapp.controller("AccountController", function($scope) {
$scope.user = {}; // Guarantee $scope.user will be defined if nothing is bound to it
$scope.saveAccount = function() {
users.current.put($scope.user, function(response) {
$scope.success.push("Update successful!");
}, function(response) {
$scope.errors.push("An error occurred when saving!");
});
};
}
myapp.factory("users", function($http) {
return {
current: {
put: function(data, success, error) {
return $http.put("/users/current", data).then(function(response) {
success(response);
}, function(response) {
error(response);
});
}
}
};
});
Another alternative is to use the binary || operator on data when calling $http.put or $http.post to make sure a defined argument is supplied:
$http.put("/users/current", data || {}).then(/* ... */);
Try this;
$http.defaults.headers.post["Content-Type"] = "application/json";
$http.post('/api/user/auth/', data).success(function(data, status, headers, config) {
// Do Stuff
})
.error(function(data, status, headers, config) {
// Do Stuff
});

Categories

Resources