Angular JS return undefined response - angularjs

I am trying to make a http request and get the results which
I am able to do in the browser with the following
http://dev.markitondemand.com/MODApis/Api/v2/InteractiveChart/json?parameters={"Normalized":false,"NumberOfDays":5,"DataPeriod":"Day","Elements":[{"Symbol":"ACN","Type":"price","Params":["c"]}]}
But when I execute the following code the response returned is undefined.Can you tell me what am I doing wrong here
var test = JSON.stringify({"Normalized":false,
"NumberOfDays":5,
"DataPeriod":"Day",
"Elements":[{"Symbol":"ACN",
"Type":"price",
"Params":["c"]
}]
});
console.log(test);
$http({
url:"http://dev.markitondemand.com/MODApis/Api/v2/InteractiveChart/json",
method : "GET",
parameters: test
}).then(
/* success */
function(response) {
var stock = {};
stock = angular.fromJson(response);
var Data = stock.Dates;
console.log(Data);
$scope.content = response.data;
$scope.statuscode = response.status;
$scope.statustext = response.statustext;
console.log('success');
},
/* failure */
function(result) {
console.log('error');
});
Please guide me

Your Content-Type in response header is not properly set.
Check whether Content-Type in response header is application/json or not.
Currently it look like this Content-Type:text/javascript; charset=UTF-8
So, your response is not recieved in JSON format.Check for proper JSON encoding

Related

Angularjs $http.post to contact form 7 with content type application/x-www-form-urlencoded

I'm successfully sending POST request from chrome postman plug-in to contact-form-7 and I receive mail and everything.
What I can't figure out is how to send same POST request from angular.
Here's what I have in postman:
POST url: http://example.com/be/home/
REQUEST:
_wpcf7:4
_wpcf7_version:4.7
_wpcf7_locale:en_US
_wpcf7_unit_tag:wpcf7-f4-p6-o1
fname:john
email:admin#example.com
subject:subject
message:message
_wpcf7_is_ajax_call:1
HEADERS:
Content-Type:application/x-www-form-urlencoded
Accept:application/json, text/javascript, */*;q=0.01
BODY(raw):
_wpcf7=4&_wpcf7_version=4.7&_wpcf7_locale=en_US&_wpcf7_unit_tag=wpcf7-f4-p6-o1&fname=john&email=admin#example.com&subject=subject&message=message&_wpcf7_is_ajax_call=1
RESPONSE:
<textarea>{"mailSent":true,"into":"#wpcf7-f4-p6-o1","captcha":null,"message":"Thank you for your message. It has been sent."}</textarea>
Here's what I tried so far:
HomeService:
this.sendMessage = function(successCallback, errorCallback){
$http.post('/be/home', {
headers:{
'Content-Type':'application/x-www-form-urlencoded',
'Accept':'application/json, text/javascript, */*;q=0.01'
},
data:{
'_wpcf7':4,
'_wpcf7_version':4.7,
'_wpcf7_locale':'en_US',
'_wpcf7_unit_tag':'wpcf7-f4-p6-o1',
'fname':'john',
'email':'admin#example.com',
'subject':'subject',
'message':'message',
'_wpcf7_is_ajax_call':1
}
}).then(function(data){
successCallback(data);
}).catch(function(data){
errorCallback(data);
});
}
}
HomeController:
HomeService.sendMessage(function(data){
console.log(data);
}, function(data){
console.log(data);
}
In response I get the whole page, I think I'm sending the headers and data wrong, but I can't figure out how to do it.
EDIT:
{"_wpcf7":4,"_wpcf7_version":4.7,"_wpcf7_locale":"en_US","_w‌​pcf7_unit... This is how REQUEST BODY looks like(JSON) I need it to look like this (form data):
_wpcf7=4&_wpcf7_version=4.7&_wpcf7_locale=en_US&_wpcf7_unit_‌​tag=wpcf7-f4-p6-o1&f‌​name=john&email=admi‌​n%40example.com&subj‌​ect=subject&message=‌​message&_wpcf7_is_aj‌​ax_call=1
And HEADERS: Content-Type:"application/x-www-form-urlencoded"
When I edit request to look like this second example, request passes and email is sent. So question is, is it possible to post Form Data instead of JSON with $http.post?
EDIT:
SOLUTION by #georgeawg
HomeService:
this.sendMessage = function(){
var config = {
//USE serializer
transformRequest: $httpParamSerializer,
headers:{
'Content-Type':'application/x-www-form-urlencoded',
'Accept':'application/json, text/javascript, */*;q=0.01'
}
};
var data = {
'_wpcf7':4,
'_wpcf7_version':4.7,
'_wpcf7_locale':'en_US',
'_wpcf7_unit_tag':'wpcf7-f4-p6-o1',
'fname':'john',
'email':'admin#example.com',
'subject':'subject',
'message':'message',
'_wpcf7_is_ajax_call':1
};
//vvvv RETURN httpPromise
return $http.post('/be/home', data, config);
};
To POST data with content type application/x-www-form-urlencoded, the data needs to be urlencoded. Use the $httpParamSerializer service:
//this.sendMessage = function(successCallback, errorCallback){
this.sendMessage = function(){
var config = {
//USE serializer
transformRequest: $httpParamSerializer,
headers:{
'Content-Type':'application/x-www-form-urlencoded',
'Accept':'application/json, text/javascript, */*;q=0.01'
}
};
var data = {
'_wpcf7':4,
'_wpcf7_version':4.7,
'_wpcf7_locale':'en_US',
'_wpcf7_unit_tag':'wpcf7-f4-p6-o1',
'fname':'john',
'email':'admin#example.com',
'subject':'subject',
'message':'message',
'_wpcf7_is_ajax_call':1
};
//vvvv RETURN httpPromise
return $http.post('/be/home', data, config);
};
The # in the email needs to be percent encoded. The param serializer will do that properly.
Also the is no need to use success and error callbacks as the $http service already returns a promise.
See Why are Callbacks from Promise .then Methods an Anti-Pattern.
In the headers, you specify 'Content-Type':'application/x-www-form-urlencoded' while you provide value in a JSON format in the data property :
data:{
'_wpcf7':4,
'_wpcf7_version':4.7,
'_wpcf7_locale':'en_US',
'_wpcf7_unit_tag':'wpcf7-f4-p6-o1',
'fname':'john',
'email':'admin#example.com',
'subject':'subject',
'message':'message',
'_wpcf7_is_ajax_call':1
}
Either don't specify 'Content-Type':'application/x-www-form-urlencoded' in order to transmit value with the "application/json" content-type that is used by default or else if you really need to use the 'application/x-www-form-urlencoded' Content-Type, provide in the data property a string conform to what 'application/x-www-form-urlencoded' expects to, that is _wpcf7=4&_wpcf7_versio=4.7... .
Try this without adding the headers in request, see this link
HomeService:
this.sendMessage = function(successCallback, errorCallback) {
var data = {
'_wpcf7': 4,
'_wpcf7_version': 4.7,
'_wpcf7_locale': 'en_US',
'_wpcf7_unit_tag': 'wpcf7-f4-p6-o1',
'fname': 'john',
'email': 'admin#example.com',
'subject': 'subject',
'message': 'message',
'_wpcf7_is_ajax_call': 1
}
return $http.post('/be/home', $.param(data));
}
HomeController:
HomeService.sendMessage().then(function(data) {
console.log(data);
});

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

how to mock response.headers('location') in jasmine?

In Angular controller, I have some codes like :
$http.save('api/purchases').$promise.then(function(response) {
var location = response.headers('location'); // to retrieve the location in response header
})
in jasmine's unit test,
it('..', function(){
$httpBackend.expectPost('api/purchase').respond(201, {}, {location: 'xxx'});
// when run the test, it reports an error with 'undefined is not a constructor' (evaluting response.headers('location'))
})
How can i test the response.headers('location')?
The Angular docs seem to indicate that respond needs statusText when given headers (as in it is not optional and is required when passing in headers)
function([status,] data[, headers, statusText])
You should be able to pass some text for a 201 like so
$httpBackend.expectPost('api/purchase').respond(201, {}, {location: 'xxx'}, 'Created');
use transformResponse in $resource action
var resource = $resource('api/purchase', {}, {
get: {
method: 'GET',
transformResponse: function(data, headers) {
var response = {};
response.data = data;
response.headers = headers();
return response;
}
}
}
to retrieve 'location':
resource.get().$promise.then(function(response){
var location = response.headers.location; // 'headers' has been put into response object above
})
then test can run normally.

Retrieve data from angular post request

right now my situation is that I have a post request from an Angular module trying to send some data to an URL handled with node.js and Express.
tickets.js:
$http(
{
method: "post",
url: "/ticketDetail",
headers: {"application/json"},
data: {detail : "test"}
}).then(function successCallback(response)
{
$scope.detail = response.data;
}, function errorCallback(response){});
app.js:
app.post("/ticketDetail", function(req, res)
{
console.log(req.data.detail);
res.json(req.data);
}
It looks like req.data is undefined.
How am I supposed to retrieve the data from my request in my URL handler?
You need to get the data from the body of the req
var qs = require('qs');
app.post('/', function(req,res){
var body = qs.parse(req.body);
var detail = body.detail;
console.log('details',detail); //prints test
});
I believe your post doesn't match the AngularJs syntax. Your $http.post should be like ;
$http.post('/ticketDetail', data, config).then(successCallback, errorCallback);
So for some reason, in your URL handler you are not supposed to access the field data: {detail : "test"} with req.data but with req.body.
app.post("/ticketDetail", function(req, res)
{
console.log(req.body.detail); // prints "test"
res.json(req.data);
}

Example of progress on file upload in AngularJS $http POST

I am trying to get a 'progress' event from AngularJS $http POST request for file upload.
After looking at $http upload file progress in AngularJS, I came across one recent angular.js git commit, that suppose to resolve the issue Add XHR progress event handling to $http and $httpBackend.
Did anyone achieve this working? And if so, can kindly show the example?
PS. I'd prefer to stay with $http rather than create my own XMLHttpRequest. The reason is that my backend expects to get json object combined with multipart file data. And the attempt to make through XMLHttpRequest is failing with error message that backend doesn't see the json object part of request "Required String parameter 'objData' is not present. The request sent by the client was syntactically incorrect." While in the POST message I see "Content-Disposition: form-data; name="objData"" in Firebug.
$scope.uploadFile = function() {
var url = buildUrl('/upload');
var data = {objData: $scope.data, fileData: $scope.file};
var formData = new FormData();
formData.append("objData", angular.toJson(data.objData));
formData.append("fileData", data.fileData);
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.open("POST", url);
xhr.setRequestHeader("Content-Type","application/json;charset=utf-8");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.send(formData);
};
At time of writing $http doesn't support the notify method of the new 1.2 $q. So you have to use jquery xhr. Its rather simple once set up:
Notice that we return a promise so your consumer of uploadFile would do uploadFile(..).then(success, fail, progress)
$scope.uploadFile = function() {
var deferred = $q.defer();
var getProgressListener = function(deferred) {
return function(event) {
//do some magic
deferred.notify(magic);
};
};
var formData = new FormData();
formData.append("objData", angular.toJson(data.objData));
formData.append("fileData", data.fileData);
$.ajax({
type: 'POST',
url: buildUrl('/upload'),
data: formData,
cache: false,
// Force this to be read from FormData
contentType: false,
processData: false,
success: function(response, textStatus, jqXHR) {
deferred.resolve(response);
},
error: function(jqXHR, textStatus, errorThrown) {
deferred.reject(errorThrown);
},
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
myXhr.upload.addEventListener(
'progress', getProgressListener(deferred), false);
} else {
$log.log('Upload progress is not supported.');
}
return myXhr;
}
});
return deferred.promise;
};

Resources