Parsing JSON in Dart - json

I'm trying to parse JSON to an object in Dart, the documentation uses Map type to parse a JSON response.
regarding to their documentation Using Dart with JSON Web Services: Parsing JSON
,I snipped the following example:
import 'dart:convert';
main() {
String mapAsJson = '{"language":"dart"}'; // input Map of data
Map parsedMap = JSON.decode(mapAsJson);
print(parsedMap["language"]); // dart
}
I applied the same in my testApp, however it didn't work
test() {
var url = "http://localhost/wptest/wp-json/wp/v2/posts";
// call the web server asynchronously
var request = HttpRequest.getString(url).then(onDataLoaded);
}
onDataLoaded(String responseText) {
Map x = JSON.decode(responseText);
print(x['title'].toString());
}
I'm getting this error
Exception: Uncaught Error: type 'List' is not a subtype of type 'Map' of 'x'.
Stack Trace:
post.post (package:untitled8/wp/posts.dart:25:24)
onDataLoaded (http://localhost:63342/untitled8/web/index.dart:24:15)
_RootZone.runUnary (dart:async/zone.dart:1166)
_Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:494)
_Future._propagateToListeners (dart:async/future_impl.dart:577)
_Future._completeWithValue (dart:async/future_impl.dart:368)
_Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:422)
_microtaskLoop (dart:async/schedule_microtask.dart:43)
_microtaskLoopEntry (dart:async/schedule_microtask.dart:52)
_ScheduleImmediateHelper._handleMutation (dart:html:42567)

The JSON coming from the sever need to be decoded to a json in dart and assigned to a map of type String and dynamic
The keys in the json have to String while their value pair has to be of type dynamic in other to hold any value be it an array or int or bool
Map<String,dynamic> z = Map<String,dynamic>.from(JSON.decode(responseText));
print(z.toString())

The documentation is correct.
//if JSON is an array (starts with '[' )
List<Map> x = JSON.decode(responseText);
print(x[0]['title']);
//if JSON is not an array (starts with '{' )
Map z = JSON.decode(responseText);
print(z['content']);
print(z['id']);
print(z['title']);

Related

JSON decoding from stream in Kotlin

I have a server set up to send messages over a local host port. I am trying to decode the serialized json messages sent by the server and get this error.
Error decoding message: kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 55: Expected EOF after parsing, but had instead at path: $
JSON input: .....mber":13,"Timestamp":5769784} .....
The Racer State messages are formatted in JSON as follows: { “SensorId”: “value”, “RacerBibNumber” : “value”, “Timestamp” : “value” }, where the value’s are character string representations of the field values. I have also tried changing my RacerStatus Class to take String instead of Int but to a similar error. Am I missing something here? The symbol that is missing in the error was not able to be copied over so I know it's not UTF-8.
I have also added
val inputString = bytes.toString(Charsets.UTF_8)
println("Received input: $inputString")
This gets
Received input: {"SensorId":0,"RacerBibNumber":5254,"Timestamp":3000203}
with a bunch of extraneous symbols at the end.
data class RacerStatus(
var SensorId: Int,
var RacerBibNumber: Int,
var Timestamp: Int
) {
fun encode(): ByteArray {
return Json.encodeToString(serializer(), this).toByteArray()
}
companion object {
fun decode(bytes: ByteArray): RacerStatus {
print(bytes[0])
try {
val mstream = ByteArrayInputStream(bytes)
return Json.decodeFromStream<RacerStatus>(mstream)
} catch (e: SerializationException) {
println("Error decoding message: $e")
return RacerStatus(0, 0, 0)
}
// return Json.decodeFromString(serializer(), mstream.readBytes().toString())
}
}
}
So I found an answer to my question. I added a regex to include just the json components I know my json contains.
val str = bytes.toString(Charsets.UTF_8)
val re = Regex("[^A-Za-z0-9{}:,\"\"]")
return Json.decodeFromString<RacerStatus>(re.replace(str,""))
I thought that Charsets.UTF_8 would remove the misc characters but it did not. Is there a more intiuative solution? Also is there a regex that would cover all possible values in json?

Dart/Flutter : Avoid Method parsing in Map , when converting to JSON?

In Dart / Flutter , when converting a map (which contains a Closure method) to json using jsonEncode , I getting following error :
Converting object to an encodable object failed: Closure: () => dynamic
The Map having :
orderedMap1["fooddelete"] = () => deleteItemFunction(
singleitem["orderId"], singleitem["id"], singleitem["shopId"]);
If commented above line , then jsonEncode works , else throwing above error .
How to instruct the jsonEncode to skip the closures when parsing Map to Json ?
It seems highly questionable to store closures in the same Map that you want to encode to JSON, but if you must, you can encode a filtered copy of it instead:
var encoded = jsonEncode({
for (var entry in orderedMap1.entries)
if (entry.value is! Function) entry.key: entry.value,
});
I suppose you alternatively could use jsonEncode's toEncodable parameter to convert closures to something else, although I'm not sure what good that would do you since there's nothing the recipient could do with it. The following will replace closures with null:
var encoded = jsonEncode(orderedMap, toEncodable: (value) {
if (value is Function) {
return null;
}
throw UnsupportedError('Cannot convert to JSON: $value');
});
option1: remove "fooddelete" key using orderedMap1.remove("fooddelete") and then parse it.
option2: put your Closure inside the double quotation. so you can save it as String.

Extract Data from JSON object in angular 2

I have this reponse as JSON object.
Object {auth_token: "60a483bc0b1bc4dc0231ff0b90a67be1dad6ef45"}
auth_token:"60a483bc0b1bc4dc0231ff0b90a67be1dad6ef45"
proto
:
Object
I want to extract "60a483bc0b1bc4dc0231ff0b90a67be1dad6ef45" from this object. How can I do that?
If you've assigned that response to a variable:
var someObject = {auth_token: "60a483bc0b1bc4dc0231ff0b90a67be1dad6ef45"};
You can extract the value by using object.key notation
var valueForKey_auth_token = this.someObject.auth_token;
console.log("valueForKey_auth_token", valueForKey_auth_token);
And you'll see this on the console
valueForKey_auth_token 60a483bc0b1bc4dc0231ff0b90a67be1dad6ef45

JsonSlurper returns No signature of method: groovy.json.JsonSlurper.parseText() is applicable for argument types: (java.util.ArrayList)

I'm trying to parse JSON file with JsonSlurper.parseText but keep getting similar problems.
def jsonParse = null
def http = new HTTPBuilder(url)
http.auth.basic(username, password)
http.request(Method.GET) {
response.success = { resp, reader ->;
jsonParse = new JsonSlurper().parseText(reader)
}
}
Whenever I run my application the error message says
No signature of method: groovy.json.JsonSlurper.parseText() is applicable for argument types: (java.util.ArrayList)
I understand that JsonSlurper.parseText() is asking for a java.util.ArrayList type as an input. So I tried the following to figure out the type of the input using this code.
def jsonParse = null
def http = new HTTPBuilder(url)
http.auth.basic(username, password)
http.request(Method.GET) {
response.success = { resp, reader ->;
jsonParse = reader
}
}
render jsonParse.getClass()
This prints out the following:
class java.util.ArrayList
I don't understand why I'm getting this error when I am feeding the input with correct datatype.
Any suggestions?
According to the documentation, the HTTPBuilder could be parsing your JSON for you. If your JSON response has its root as a JSON array, then that explains the ArrayList object in your reader variable.
Regarding how this explains the exception being thrown. The reader parameter of the Closure is an ArrayList of parsed JSON, not a String of unparsed JSON. Thus, the code fails on new JsonSlurper().parseText(reader) because reader is not text and the JsonSlurper does not have a method defined for how to parse an ArrayList as JSON.

Grails generic JSON handling of request and response

i asked myself if there is a generic approach where i can parse requests in a generic way or add fields to a JSON response with every response sent.
I would like to receive and parse something like:
{
transactionId:456, // every response contains this
statuscode:1,
content:{ // only content is changing
{
class:"org.something.test",
id:123,
name:"test",
referenceIdToOtherClass:345
}
}
}
The contents of "content" should be converted e.g. to an instance of the given class.
The response should work also in such generic way (changing content, some fields always).
Would you reccomend a JSON marshaller, a Filter or something different?
Thank you
You can convert the json to a map with JSON.parse
import grails.converters.*
import org.codehaus.groovy.grails.web.json.*; // package containing JSONObject, JSONArray,...
def o = JSON.parse("{ foo: 'bar' }"); // Parse a JSON String
assert o instanceof JSONObject // In this case, JSON.parse returns a JSONObject instance
assert o instanceof Map // which implements the Map interface
assert o.foo == 'bar' // access a property
and then you can pass the map to your constructor to create a new instance
from http://grails.org/Converters+Reference