JSON deserialization with angular.fromJson() - json

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.

Related

node request module: parsing XML as JSON

Until recently I've been fetching XML data using the node request module, and then running that XML through an XML to JSON converter. I discovered by accident that if I set json: true as an option (even knowing the endpoint returns XML, not JSON), I was actually getting back JSON:
var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'stackoverflow question (https://stackoverflow.com/q/52609246/4070848)' } };
options.uri = 'https://api.met.no/weatherapi/locationforecast/1.9/?lat=40.597&lon=-74.26';
request(options, function (error, response, body) {
console.log(`body for ${options.uri}: ${JSON.stringify(body)}`);
});
The above call returns JSON, whereas the raw URL is actually sending XML. Sure enough, with json: false the returned data is XML:
var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'stackoverflow question (https://stackoverflow.com/q/52609246/4070848)' } };
options.uri = 'https://api.met.no/weatherapi/locationforecast/1.9/?lat=40.597&lon=-74.26';
options.json = false; // <<--- the only difference in the request
request(options, function (error, response, body) {
console.log(`body for ${options.uri}: ${body}`);
});
So I thought "that's handy", until I tried the same trick with a different URL that also returns XML, and in this case the returned data is still XML despite using the same request options:
var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'stackoverflow question (https://stackoverflow.com/q/52609246/4070848)' } };
options.uri = 'https://graphical.weather.gov/xml/SOAP_server/ndfdXMLclient.php?whichClient=NDFDgen&lat=40.597&lon=-74.26&product=time-series&temp=tempSubmit=Submit';
request(options, function (error, response, body) {
console.log(`body for ${options.uri}: ${body}`);
});
What is the difference here? How do I get the latter request to return the data in JSON format (so that I can avoid the step of converting XML to JSON myself)? Maybe the endpoint in the first example can detect that JSON is requested and it does in fact return JSON rather than XML?
EDIT weirdly, the first request is now returning XML rather than JSON even with json: true. So maybe this behaviour was down to what was being sent from the endpoint, and they've changed this even since I posted a few hours ago
So now that the behavior is unrepeatable, the answer is less useful for your particular problem, but I think it's worth pointing out that when you set json:true on the request module, it does a few things under the hood for you:
Sets the Accept header to 'application/json'
Parses the response body using JSON.parse()
Request types with a body also get the body automatically serialized as JSON
Request types with a body also get the Content-Type header added as 'application/json'
So perhaps they did change it, but there are plenty of web services I've seen that will detect the content-type to send based on the Accept header and respond appropriately for some set of types that make sense (usually XML or JSON, but sometimes CSV, TXT, HTML, etc).
To handle XML query, I usually do something like this using the request module:
import parser from "xml2json";
const resp = await rp({
method: "POST",
url: 'some url',
form: {xml_query}, // set XML query to xml_query field
});
const parsedData = parser.toJson(resp, {
object: true, // returns a Javascript object instead of a JSON string
coerce: true, // makes type coercion.
});

How to send data to server using angular.tojson?

Well, i'm having some difficult to understand the use of angular.toJson. I completely understand that it changes to a json object...
But, how can i send this obj to the server ?
The server already gives a json obj when 'GET', but how use it to 'POST' and others?
sorry, i'm new :)
You can create factory in your app:
var app = angular.module('myApp', []);
app.factory('requestsFactory', ['$http', function ($http) {
return {
postData: function (data) {
var url = // some url to send your data
return $http.post(data, url);
};
};
}];
And now, you can post your data from controllers:
app.controller('yourController', ['$scope', 'requestsFactory', function ($scope, requestsFactory) {
...
requestFactory.postData(anyData).success(function (result) {
// if server send any response
}
...
}]);
Also you can use $http for GET, PUT, DELETE requests. Click here for more information
You don't actually need to call angular.toJson() yourself when posting data to a server or retrieving data from the server using the $http service.
This is the default behaviour that Angular does for you.
From the docs:
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.

Angular $http service - force not parsing response to 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.

How to parse the json response of backbone js in the backbone view?

How to parse the response JSON returned from the RESTfull service for the Backbone js
fetch()
I get the JSON is in the following format.
[{"custId":7,"cookieNum":"","emailId":"raju.allen1888#gmail.com","facebookId":"","twitterId":"","gmailId":"","mobilePhone":""},{"custId":8,"cookieNum":"","emailId":"raju#gmail.com","facebookId":"","twitterId":"","gmailId":"","mobilePhone":""}]
but when i print the response in the console
Object { custId=7, tenantId=1, emailId="raju.allen1888#gmail.com", more...}
how to parse the response to take the "custId" and "emailId" from the response json in backbone.js
since i'm new to backbone i couldn't figure it out.
parse: function(response, xhr) {
return {
"custId": response.custId,
"emailId": response.emailId
}
}
fetch() uses parse(). Override parse to use selected data.
This code snippet does the job for me.
this.getSegment = new CustomerCollection();
this.getSegment.fetch({
success: function(response) {
var data = response.toJSON();
console.log(data[0].custId);
}
});
i looped it to the length of the json to get custId of all the JSON.

Getting json object

first time using json. I currently send a postcode to a php page, and try to store the result as json:
$("#make_ajax_call").click(function()
{
var form_postcode = $("#postcode").val();
$.ajax({
type: "POST",
url: 'mapping-ajax.php',
data: { postcode: form_postcode},
success: function(data)
{
var jsonObject = data;
var trimmedpostcode = jsonObject.trimmedpostcode;
alert(jsonObject);
alert(jsonObject.trimmedpostcode);
$('#result').html(data);
//alert('Load was performed.');
}
});
});
On the other end I use a php function echo json_encode($return_array);
The two alerts give me:
{"trimmedpostcode":"CO125WL","success":true,"outputstring":"CO125WL<br\/>"}
and
Undefined
How come the second one doesn't return "CO125WL"? Do I need to tell javascript its a json object somehow?
Have you tried:
dataType: 'json'
This is how I pull in my json information in Javascript with an ajax call.
You got it. You need to call:
var obj = JSON.parse(jsonstr);
That will parse the JSON into a JavaScript Object.
Do I need to tell javascript its a json object somehow?
Yes, you will need to tell it that it's a json string. Set the mimetype of your response to the appropriate "application/json", and jQuery's intelligence will parse the text automatically and call your success function with an object instead of a string.
Or you can set the dataType of your jQuery call to "json", see the jQuery.ajax() documentation.