Angular $http service - force not parsing response to JSON - json

I have a "test.ini" file in my server, contain the following text:
"[ALL_OFF]
[ALL_ON]
"
I'm trying to get this file content via $http service, here is part of my function:
var params = { url: 'test.ini'};
$http(params).then(
function (APIResponse)
{
deferred.resolve(APIResponse.data);
},
function (APIResponse)
{
deferred.reject(APIResponse);
});
This operation got an Angular exception (SyntaxError: Unexpected token A).
I opened the Angular framework file, and I found the exeption:
Because the text file content start with "[" and end with "]", Angular "think" that is a JSON file.
Here is the Angular code (line 7474 in 1.2.23 version):
var defaults = this.defaults = {
// transform incoming response data
transformResponse: [function(data) {
if (isString(data)) {
// strip json vulnerability protection prefix
data = data.replace(PROTECTION_PREFIX, '');
if (JSON_START.test(data) && JSON_END.test(data))
data = fromJson(data);
}
return data;
}],
My question:
How can I force angular to not make this check (if (JSON_START.test(data) && JSON_END.test(data))) and not parse the text response to JSON?

You can override the defaults by this:
$http({
url: '...',
method: 'GET',
transformResponse: [function (data) {
// Do whatever you want!
return data;
}]
});
The function above replaces the default function you have posted for this HTTP request.
Or read this where they wrote "Overriding the Default Transformations Per Request".

You can also force angular to treat the response as plain text and not JSON:
$http({
url: '...',
method: 'GET',
responseType: 'text'
});
This will make sure that Angular doesn't try to auto detect the content type.

Related

Printing JSON data member into console with angular.js

I want to access JSON object member using angularjs. I can print the whole json object array but can't access the member of the object uniquely.
$scope.rows = []; // init empty array
$scope.datainput =[];
$http({
method: 'GET',
url: 'Data/input.json'
}).then(function (data){
$scope.datainput=data;
//console.log($scope.datainput);
console.log($scope.datainput);
},function (error){
console.log("big error");
});
var json=JSON.parse($scope.datainput);
console.log(json[0].status);
I have tried this code also but still geting the same error .
$scope.temp = "";
$scope.rows = []; // init empty array
$scope.datainput =[];
$http({
method: 'GET',
url: 'Data/input.json'
}).then(function (data){
$scope.datainput=data;
//console.log($scope.datainput);
console.log($scope.datainput);
var json=JSON.parse($scope.datainput);
console.log(json[0].status);
},function (error){
console.log("big error");
});
json file input.json:
[
{"status":"payfail","value":"310"},
{"status":"payinit","value":"100"},
{"status":"paysuccess","value":"200"},
{"status":"payreturn","value":"50"}
]
I get this error :
SyntaxError: Unexpected end of JSON input
at JSON.parse ()
The solution will be this....
$scope.rows = []; // init empty array
$scope.datainput =[];
$http({
method: 'GET',
url: 'Data/input.json'
}).then(function (data){
$scope.datainput=data.data;
//console.log(data);
console.log($scope.datainput);
var json=JSON.parse(JSON.stringify($scope.datainput));
console.log(json[0].status);
},function (error){
console.log("big error");
});
My guess would be that you are trying to parse the JSON string before it has been returned by the promise.
Try putting your parsing code inside the then block so that it executes in the correct order.
Upon further investigation, here is an updated Answer:
In addition to fixing the promise execution order, it turns out there is an issue with the way that you are accessing the data on the response variable.
Check the documentation for $http here: W3Schools.com $http doco
You will see that the callback response value actually contains a member called data for the response payload. To get this working try accessing the data member on the response object.
$scope.datainput=data.data;
It would probably be a good idea to also rename the data response object from data to response for readability.
You can use this code to solve that:
$scope.rows = []; // init empty array
$scope.datainput =[];
$http({
method: 'GET',
url: 'Data/input.json'
}).then(function (data){
$scope.datainput=data.data;
console.log($scope.datainput);
var json= angular.fromJson($scope.datainput);
console.log(json[0].status);
},function (error){
console.log("big error");
});
You should'n write Json.Parse out function Get you should write this code inside the then block and use data.data to get the data from json file.

Handling (read) of Base64 encoded files in a Logic App, and post to endpoint

I have a Logic App that gets the contents from a SharePoint (.xlsx) and posts the body to an endpoint to get processed. now the content I see is a base64-encoded file, what I wanted to do was to post this data as is.
when I try to post it using postman it gets accepted successfully but when it is posted form the Logic app I get
BadRequest. Http request failed: the content was not a valid JSON.
but I can see that the body that was meant to be sent is of the type, which is a valid Json
{
"$content-type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"$content": "AA....VeryLong...B1241BACDFA=="
}
also tried this expression
decodeBase64(triggerBody()?[body('getFile')])
but I get a different error
InvalidTemplate. Unable to process template language expressions in action 'HTTP' inputs at line '1' and column '2565': 'The template language expression 'decodeBase64(triggerBody()?[body('getFile')])' cannot be evaluated because property '{
"$content-type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"$content": "UEsDBBQABgAIAAAAIQDuooLHjAEAAJkGAAATAAgCW0Nvb...
What I want to achieve is simple really I want to post to my end point the Json as is or the contents of the base64Encoded string.
If you decode the content with base64 you will find the content is garbled. This is because the content is in ooxml format then encoded with base64. And in logic app you could not decode the ooxml.
First solution, you could use Azure Function to write a method to read the document then return the content. Then in logic app call the function to get the content.
Second solution, change your file to a directly readable file(like .txt file), this way I tried and you could parse it Json.
Can you send me your postman request save it in collect and then export as file.
I think what you can do in postman can be done in logic app too.
Or send me your code I can modify it.Make sure you have post as body and it matches the parameter of Post at web api level.
var Webrequestdata = {
"webserviceurl": "http://examplecom/u/b/b/e.ee.msg",
"username": "123"
};
$.ajax({
cache: false,
type: "POST",
url: 'http://example.com/res/api/Outlookapi',
data: JSON.stringify(Webrequestdata),
contentType: "application/json",
success: function (result) {
console.log("email sent successfully");
},
error: function (response) { alert('Error: ' + response.responseText); }
});
after looking at your statement:
Logic App gets the contents from a SharePoint (.xlsx) and posts the
body to an endpoint to get processed. now the content I see is a
base64-encoded file
i assume your endpoint is still looking for a content type -
vnd.openxmlformats-officedocument.spreadsheetml.sheet
but you are passing a Base64 String
1) check if your "content-type" header is correctly placed change it to application/json if possible
2) Make sure you are processing the base64 string correctly.
In my case, I extracted the base64 string from an image file using Javascript. I got special keys at the start of base64 string like ''data:image/png;base64','ACTUAL BASE 64 STRING...' so i removed the special keys before the actual base64 string with some regular expression.
This sample Json request might help in attaching the base64 Content
Make sure you are converting your request to JSON using JSON.stringify
//var finalString = srcData.replace('data:image/png;base64,','');
var finalString = srcData.replace(/^,+?(\,)/, '');
finalString = srcData.substring(srcData.indexOf(',')+1, srcData.length);
var data = JSON.stringify({
"requests": [
{
"image": {
"content": finalString
},
"features":
[
{
"type": "DOCUMENT_TEXT_DETECTION",
"maxResults": 1
}
]
}
]
});
This is the XMLHttpRequest i used:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
var obj = JSON.parse(this.responseText);
try
{
//do something
}catch(err)
{
//do something
}
}
});
try {
xhr.open("POST", "https://vision.googleapis.com/v1/images:annotate?key=blablabla");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("Postman-Token", "111111111");
xhr.send(data);
}
catch(err) {
//do something
}

JSON deserialization with angular.fromJson()

Despite from the AngularJS documentation for angular.fromJson being spectacular, I still don't know how to use it to its fullest potential. Originally I have just been directly assigning the JSON data response from an HTTP request to a $scope variable. I've recently noticed that Angular has a built-in fromJson() function, which seems like something I'd want to use. If I use it, is it safer and can I access data elements easier?
This is how I've been doing it:
$http({
method: 'GET',
url: 'https://www.reddit.com/r/2007scape.json'
}).then(function success(response) {
var mainPost = response; // assigning JSON data here
return mainPost;
}, function error(response) {
console.log("No response");
});
This is how I could be doing it:
$http({
method: 'GET',
url: 'https://www.reddit.com/r/2007scape.json'
}).then(function success(response) {
var json = angular.fromJson(response); // assigning JSON data here
return json;
}, function error(response) {
console.log("No response");
});
It is pointless to convert the response to json as angular does it for you. From angular documentation of $http:
Angular provides the following default transformations:
Request transformations ($httpProvider.defaults.transformRequest and $http.defaults.transformRequest):
If the data property of the request configuration object contains an object, serialize it into JSON format.
Response transformations ($httpProvider.defaults.transformResponse and $http.defaults.transformResponse):
If XSRF prefix is detected, strip it (see Security Considerations section below).
If JSON response is detected, deserialize it using a JSON parser.

Send generic JSON data to MVC2 Controller

I have a javascript client that is going to send json-formatted data to a set of MVC2 controllers. The client will format the json, and the controller will have no prior knowledge of how to interpret the json into any model. So, I can't cast the Controller method parameter into a known model type, I just want to grab the generic json and pass it to a factory of some sort.
My ajax call:
function SendObjectAsJSONToServer(object,url,idForResponseHTML) {
// Make a call to the server to process the object
var jsonifiedObject = JSON.stringify(object);
$.ajax({
url: url // set by caller
, dataType: 'json'
, data: jsonifiedObject
, type: 'GET'
, error: function(data) { alert('error in sendObjectAsJSONToServer:' + data); }
, success: function(data) {
alert(data.message); // Note that data is already parsed into an object
}
});
}
My MVC Controller:
public ActionResult SaveForm(string obj)
{
// Ok, try saving the object
string rc = PassJSONToSomething(obj.ToString());
string message = "{\"message\":\""+rc+"\",\"foo\":\"bar\"}";
return new ContentResult { Content = message, ContentType = "application/json" };
}
The problem is that obj is always null. Can anyone tell me how I should structure the ajax call and the controller parameter so that I get my json to the server? I'm using MVC2. This may appear to be a duplicate of some SO questions, but in my case I do not know the Model that the json maps to, so I can't use a specific model type in the controller parameter type.
Thanks very much.
Have you tried something like that?
$.ajax({
url: url // set by caller
, dataType: 'json'
, data: {obj :jsonifiedObject}
, contentType: 'application/json; charset=utf-8'
, type: 'GET'
, error: function(data) { alert('error in sendObjectAsJSONToServer:' + data); }
, success: function(data) {
alert(data.message); // Note that data is already parsed into an object
}
});

Parse JSON from JQuery.ajax success data

I am having trouble getting the contents of JSON object from a JQery.ajax call. My call:
$('#Search').click(function () {
var query = $('#query').valueOf();
$.ajax({
url: '/Products/Search',
type: "POST",
data: query,
dataType: 'application/json; charset=utf-8',
success: function (data) {
alert(data);
for (var x = 0; x < data.length; x++) {
content = data[x].Id;
content += "<br>";
content += data[x].Name;
content += "<br>";
$(content).appendTo("#ProductList");
// updateListing(data[x]);
}
}
});
});
It seems that the JSON object is being returned correctly because "alert(data)" displays the following
[{"Id": "1", "Name": "Shirt"}, {"Id": "2", "Name":"Pants"}]
but when I try displaying the Id or Name to the page using:
content = data[x].Id;
content += "<br>";
content += data[x].Name;
content += "<br>";
it returns "undefined" to the page. What am I doing wrong?
Thanks for the help.
The data is coming back as the string representation of the JSON and you aren't converting it back to a JavaScript object. Set the dataType to just 'json' to have it converted automatically.
I recommend you use:
var returnedData = JSON.parse(response);
to convert the JSON string (if it is just text) to a JavaScript object.
It works fine,
Ex :
$.ajax({
url: "http://localhost:11141/Search/BasicSearchContent?ContentTitle=" + "تهران",
type: 'GET',
cache: false,
success: function(result) {
// alert(jQuery.dataType);
if (result) {
// var dd = JSON.parse(result);
alert(result[0].Id)
}
},
error: function() {
alert("No");
}
});
Finally, you need to use this statement ...
result[0].Whatever
One of the way you can ensure that this type of mistake (using string instead of json) doesn't happen is to see what gets printed in the alert. When you do
alert(data)
if data is a string, it will print everything that is contains. However if you print is json object. you will get the following response in the alert
[object Object]
If this the response then you can be sure that you can use this as an object (json in this case).
Thus, you need to convert your string into json first, before using it by doing this:
JSON.parse(data)
Well... you are about 3/4 of the way there... you already have your JSON as text.
The problem is that you appear to be handling this string as if it was already a JavaScript object with properties relating to the fields that were transmitted.
It isn't... its just a string.
Queries like "content = data[x].Id;" are bound to fail because JavaScript is not finding these properties attached to the string that it is looking at... again, its JUST a string.
You should be able to simply parse the data as JSON through... yup... the parse method of the JSON object.
myResult = JSON.parse(request.responseText);
Now myResult is a javascript object containing the properties that were transmitted through AJAX.
That should allow you to handle it the way you appear to be trying to.
Looks like JSON.parse was added when ECMA5 was added, so anything fairly modern should be able to handle this natively... if you have to handle fossils, you could also try external libraries to handle this, such as jQuery or JSON2.
For the record, this was already answered by Andy E for someone else HERE.
edit - Saw the request for 'official or credible sources', and probably one of the coders that I find the most credible would be John Resig ~ ECMA5 JSON ~ i would have linked to the actual ECMA5 spec regarding native JSON support, but I would rather refer someone to a master like Resig than a dry specification.
Try the jquery each function to walk through your json object:
$.each(data,function(i,j){
content ='<span>'+j[i].Id+'<br />'+j[i].Name+'<br /></span>';
$('#ProductList').append(content);
});
you can use the jQuery parseJSON method:
var Data = $.parseJSON(response);
input type Button
<input type="button" Id="update" value="Update">
I've successfully posted a form with AJAX in perl. After posting the form, controller returns a JSON response as below
$(function() {
$('#Search').click(function() {
var query = $('#query').val();
var update = $('#update').val();
$.ajax({
type: 'POST',
url: '/Products/Search/',
data: {
'insert': update,
'query': address,
},
success: function(res) {
$('#ProductList').empty('');
console.log(res);
json = JSON.parse(res);
for (var i in json) {
var row = $('<tr>');
row.append($('<td id=' + json[i].Id + '>').html(json[i].Id));
row.append($('<td id=' + json[i].Name + '>').html(json[i].Name));
$('</tr>');
$('#ProductList').append(row);
}
},
error: function() {
alert("did not work");
location.reload(true);
}
});
});
});
I'm not sure whats going wrong with your set up. Maybe the server is not setting the headers properly. Not sure. As a long shot, you can try this
$.ajax({
url : url,
dataType : 'json'
})
.done(function(data, statusText, resObject) {
var jsonData = resObject.responseJSON
})
From the jQuery API: with the setting of dataType, If none is specified, jQuery will try to infer it with $.parseJSON() based on the MIME type (the MIME type for JSON text is "application/json") of the response (in 1.4 JSON will yield a JavaScript object).
Or you can set the dataType to json to convert it automatically.
parse and convert it to js object that's it.
success: function(response) {
var content = "";
var jsondata = JSON.parse(response);
for (var x = 0; x < jsonData.length; x++) {
content += jsondata[x].Id;
content += "<br>";
content += jsondata[x].Name;
content += "<br>";
}
$("#ProductList").append(content);
}
Use
dataType: 'json'
In .NET you could also return Json(yourModel) in your action method/API controller.
And parse the returned JSON as follows in the Jquery .ajax:
if you've a complex object: navigate to it directly.
success: function (res) {
$.each(res.YourObject, function (index, element) {
console.log(element.text);
console.log(element.value);
});
});