How to handle non-json data and deserialize it in Flutter? - json

I'm working on a project in flutter and I'm trying to use an API for CO2 Emissions. The endpoint of the API can be found here: http://www.hqcasanova.com/co2/?callback=callback. I'm having issues parsing the data because it isn't valid JSON notation. Is there a way to handle this inconvenience?
This is the current code I have:
Future<CO2Model> fetchCarbonEmissionData() async {
var response = await http.get('http://www.hqcasanova.com/co2/?callback=callback/');
RegExp exp = new RegExp(r"callback\((.*)\)");
var match = exp.firstMatch(json.encode(response.body));
print(match.group(0));
try {
if(response.statusCode == HTTP_SUCCESS_CODE) {
var jsonData = jsonDecode(response.body);
var data = jsonData['callback'];
CO2Model instance = CO2Model.fromJSON(data);
return instance;
} else {
print('failed');
}
} catch (e) {
throw e;
}
}
Note: Above I tried to use Regular Expressions to deal with this, but I'm unable to do so.

I do not suggest you use a regex for such a simple task, especially if you sure that you will always get something like
callback(...)
you could simply trim spaces, and get the substring you want. However, if you want to do it with regex
r'callback\((.*).*\)'
It basically does what I suggested before, take the match that starts begins with the word callback then group the part of the match you want as output (excluding the trailing parenthesis). I hope this helps.

Related

typescript - load json from url and get access to array of json objects

I just can't find a working solution and implement in my format.
There is a JSON file which is returned to me by URL. Its format is:
{"success":true,
"data":[
{
"loadTimestamp":"2022-07-20T15:12:35.097Z",
"seqNum":"9480969",
"price":"45.7",
"quantity":"0.2",
"makerClientOrderId":"1658329838469",
"takerClientOrderId":"1658329934701"
},
{
"loadTimestamp":"2022-07-20T14:49:11.446Z",
"seqNum":"9480410",
"price":"46",
"quantity":"0.1",
"makerClientOrderId":"1658328403394",
"takerClientOrderId":"0"
}]
}
Due to the fact that it is returned via the URL, it is not possible to directly use the object, for example:
myobj['data']['price']
I have either a string of data that I can convert using JSON.parse() or an object right away.
But for some reason I can't use it directly.
As far as I understand, this is a JSON file inside which is an array of JSON data.
My goal is to display all the data from the array, while taking for example 2 values: price, quantity
How can I access the values that I want to get?
Ok I find, what I was looking for.
I return result not in json, but in text response.text()
After I did this, I create a new constant called res and put in it JSON.parse(data)
const url = 'https://myurl.com/'+pub_key
const response = await fetch(url)
let data = ''
if (response.ok) { data = await response.text() } else { console.log("Error HTTP: " + response.status) }
const res = JSON.parse(data)
After all this manipulations I can use my data with 2 ways:
console.log(res["data"][0]["price"])
console.log(res.data[0].price)
Or I can make a cocktail from it, by using my favorite blender :)))
if(res.success==true){
for(let item in res.data){
console.log(res.data[item].price,res.data[item].quantity)
}
}

Node-RED parse json

I am trying to pull out the value "533"
{
"d": {
"ItemValue_1": 533
},
"ts": "2021-01-20T10:59:41.958591"
}
This does not work
var ItemValue_1 = msg.payload.ItemValue_1;
msg.payload = ItemValue_1;
return msg;
My result is unsuccessful
I was able to solve on my own, it works.
sensorMeasurement=JSON.parse(msg.payload);
msg.payload=sensorMeasurement.d;
var msgout = {payload : msg.payload.ItemValue_1}
return msgout;
The better way to do this is as follows:
Add a JSON node before the function node, this will turn a string payload in to a JSON object (assuming the string actually represents a JSON object).
Then if you are using a function node the following:
msg.payload = msg.payload.d.ItemValue_1;
return msg;
It is bad practice to create a new object as you did in your answer as it throws away any meta data that may be required later that is attached to the original object.
Rather than use a function node it would also be cleaner to use a change node and the Move mode to shift the msg.payload.d.ItemValue_1 to msg.payload

Asserting entire response body in post man

I recently started working on spring boot projects.
I am looking for a way to assert the entire response of my API.
The intention of this is to reduce the testing time taken for the API.
Found A few solutions mentioned below, but nothing helped me resolve the issue.
pm.test("Body matches string", function () {
pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});
pm.test("Body is correct", function () {
pm.response.to.have.body("response_body_string");
});
When I put the entire response body as an argument, I get the below errors.
Unclosed String
2.
3.
If you want to use the same type of quotes you defined the string with inside it, you have to escape them:
'string with "quotes"'
"string with 'quotes'"
'string with \'quotes\''
"string with \"quotes\""
You probably want to put your json in single quotes as they are not allowed by json itself.
You could try setting the response as a variable and then assert against that?
var jsonData = pm.response.json()
pm.environment.set('responseData', JSON.stringify(jsonData))
From here you can get the data JSON.parse(pm.enviroment.get('responseData')) and then use this within any test to assert against all of the values.
pm.test("Body is correct", () => {
var jsonData = pm.response.json()
pm.expect(jsonData).to.deep.equal(JSON.parse(pm.environment.get('responseData')))
})
My reasoning is that you’re trying to assert against JSON anyway but doing as a plain text string.
Or you could assert against the values separately like this:
pm.test("Body is correct", () => {
var jsonData = pm.response.json()
pm.expect(jsonData[0].employeeName).to.equal("tushar")
pm.expect(jsonData[0].phNum).to.equal(10101010)
})
Depending on the JSON structure you may not need to access an array of data and the [0] can be dropped.

cordova readAsText returns json string that can't be parsed to JSON object

I read my json file using http and cordova file readAsText functions.
http request returns an object which is ok.
cordova file readAsText function return 'string' which contain extra "r\n\" symbols. This make it impossible to use JSON.parse(evt.target.result)
function readJson(absPath, success, failed){
window.resolveLocalFileSystemURL(absPath, function (entry) {
entry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function (evt) {
success(evt.target.result);
};
reader.readAsText(file);
}, failed);
}, failed);
}
readJson(cordova.file.dataDirectory + 'my.json', function(res){
console.log(JSON.parse(res)); //here I've got an parsing error due to presence of r\n\ symbols
}, failed );
How to read JSON files using cordova?
UPDATE:
funny thing that the following works:
a = '{\r\n"a":"1",\r\n"b":"2"\r\n}';
b = JSON.parse(a);
so the problem not only with \r\n... there is something else that is added by cordova readAsText
UPDATE2
as a workaround I use now var object = eval("(" + res + ")")
Still search for a common way to load json objects...
No one has answered this and I just had to solve it for my project, so I will post my solution.
The readAsText method outputs a string, so you CAN actually run a replace on it, but what you need to do is use a RegExp to find the newline character. here's my solution:
var sanitizerRegex = new RegExp(String.fromCharCode(10), 'g');
var sanitizedData = JSON.parse(result.replace(sanitizerRegex, ''));
I've used the String method fromCharCode to get the specific newline character and the "g" flag to match all instances in the entire string. The problem with your string solution is that you can't do a string replace using the characters for backslash and "n" because the issue is the actual new line character, which is merely represented as "\n".
I do not know the reason JSON.parse can't handle the newline character, or why the file plugin introduces this problem, but this solution seems to work for me.
Also, NEVER use eval like this if you can avoid it, especially on input from a source like a JSON file. Even in a cordova app, using eval is potentially very unsafe.
I found out the solution after debug deeply. readAsText function returned text has one more letter at the first position of text.
Example:
{"name":"John"} => ?{"name":"John"} (?: API didn't return ?, just one string)
I confirmed this with length of result, so we need to use substr(1) before parse JSON.
fileContent = fileContent.substr(1);
var jData = jQuery.parseJSON(fileContent);

How to get the values from the Json using Jquery

Hi I'm new to Jquery and i don't know how to use json data. I have a Json which is coming as a response. My success function is
success: function(resp)
{
var x = JSON.stringify(resp);
alert(x);
}
alert is having following JSON
{"xyz":{"abc":[{"action":"fail","result":"xxx"},{"action":"pass","resut":"yyy"}]}}
I want action value alone. How can i get this value from x variable and how can i utilize this value in HTML. Thanks in advance.
When you use JSON.stringify() you are turning it into a string, you want it as an object to access the data. Try this:
success: function(resp) {
alert(resp.xyz.abc[0].action);
var x = resp.xyz.abc[0].action // to use the value in html later on
}
If it is returned as a string (I can't tell at this point), you can turn it into an object (as long as it is valid JSON) by using $.parseJSON()
success: function(resp)
{
var x = $.parseJSON(resp);
var xyz = x.xyz;
var pass = x.xyz.abc[1].action;
}
or you can loop though each of the array by $.each
success: function(resp)
{
var x = $.parseJSON(resp);
$.each(x.xyz.abc, function(index, element){
alert('action:' + element.action + ', result:' + element.resut)
});
}
i think, and don't take it personally,that your JSON object is not well organized as an object to get and to have. Action,from my perspective is either fail or success, and reading it, as you saw in the above good answer, will give you exactly what you want.
What's the point in getting a JSON with data structured like you did, with 2 possible answers encoded in it, when there is only one available (either success or fail).