I am using SQFlite to store data locally, I have a table in which I have a field called 'json', this field is of type TEXT and stores a json converted to String, such as: '{name: Eduardo, Age: 23, Sex: male}'.
Up to this point, everything works fine.
But then I need to consult this information from the database and how it is stored in a text type format flutter recognizes it as a string. I don't know how to convert it back to an object.
I know that I can build a function to solve this, in the case that the information stored in the json always complies with the same structure. But in my case, the information contained by the json will be variable.
Is there a way to solve this problem?
you can Simply use json.decode function from the dart:convert package.
example:
import 'dart:convert';
main() {
final jsonString = '{"key1": 1, "key2": "hello"}';
final decodedMap = json.decode(jsonString);
// we can now use the decodedMap as a normal map
print(decodedMap['key1']);
}
check those links for more details
https://api.dart.dev/stable/2.10.3/dart-convert/json-constant.html
https://api.dart.dev/stable/2.4.0/dart-convert/dart-convert-library.html
if you have issue that your json keys doesn't have quotes then try this code it transform the unquoted String to a quoted String and then decode it , it's 100% working
final string1 = '{name : "Eduardo", numbers : [12, 23], country: us }';
// remove all quotes from the string values
final string2=string1.replaceAll("\"", "");
// now we add quotes to both keys and Strings values
final quotedString = string2.replaceAllMapped(RegExp(r'\b\w+\b'), (match) {
return '"${match.group(0)}"';
});
// decoding it as a normal json
final decoded = json.decode(quotedString);
print(decoded);
#EduardoColon If the keys are not quoted, then it's not JSON, it's your own custom key-value format. JSON keys have to be quoted. See https://json.org for the "official" JSON syntax.
Related
I have an object with the following structure:
enum class GeometryType { ... }
data class GeometryItem(
val type: GeometryType,
val geomtryJson: String
)
Where an example json could be:
{
type: "Point",
geometryJson: [12.0, 11.0]
}
So gemetryJson is a valid json string, but not quoted.
Could this be accomplished using Kotlin Serialization module?
According to JSON RFC:
A JSON value MUST be an object, array, number, or string, or one of
the following three literal names: false null true.
The representation of strings is similar to conventions used in the C
family of programming languages. A string begins and ends with
quotation marks.
An array structure is represented as square brackets surrounding
zero or more values (or elements). Elements are separated by
commas.
So the value of geometryJson: [12.0, 11.0] has array type, not a string type.
As for kotlinx-serialization out of the box it won't handle such deserialization. You can try to write your own decoder, but I would suggest to use Jackson library for this task. Not a full solution:
val mapper = jacksonObjectMapper()
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
val json ="""
{
type: "POINT",
geometryJson: "[12.0, 11.0]"
}
""".trimIndent()
val geometryItem = mapper.readValue<GeometryItem>(json)
println("geometryItem = $geometryItem")
With such config you can handle at least unquoted json fields.
As for reading array values I would suggest to read it to array of doubles, and if you need to represent it as string use such conversion:
val stringArray = doubleArray.map { it.toString() }.toTypedArray().contentToString()
I want to get a nested field in a json string using JSONPath.
Take for example the following json:
{
"ID": "2ac464eb-352f-4e36-8b9f-950a24bb9586",
"PAYLOAD": "{\"#type\":\"Event\",\"id\":\"baf223c4-4264-415a-8de5-61c9c709c0d2\"}"
}
If I want to extract the #type field, I expect to do it like this
$.PAYLOAD.#type
But that doesn't seem to work..
Also tried this:
$.PAYLOAD['#type']
Do I need to use escape chars or something?
Posting my comment as an answer
"{\"#type\":\"Event\",\"id\":\"baf223c4-4264-415a-8de5-61c9c709c0d2\"}"
Isn't JSON, it's a string containing encoded JSON.
Since JsonPath can't decode such string, you'll have to use a language of your desire to decode the string.
Eg: Decoding JSON String in Java
I´m making an application with dart / flutter and I need to keep the escape keys from the json server api response, how can I do that?
Example:
JSON reponse:
{"\"\"example\"\"": "value\'"}
Goal (after .fromJson and json.decode):
Class.example = "\"\"example\"\"";
Class.value = "value\'";
If you do jsonDecode(r'{"\"\"example\"\"": "value\'"}'), then you get a map with the key ""example"" and the value value' (the quotes are part of the string content here, not delimiters).
The backslashes are removed, which is to be expected because that's what the JSON specification says should happen. The escaped quotes are retained. The key does not become just example.
If you want to retain the backslashes too, then you don't actually want JSON decoding, because JSON decoding treats \" inside a string literal as introducing the character ".
If you wanted a string containing \"\"example\"\" from JSON decoding, then the original source needed to be "\\\"\\\"example\\\"\\\"".
So, if the sender of the JSON wanted you to see backslashes, they should have included and escaped those backslashes too.
If you JSON encode the string back, you get the backslashes again (at least for "), since jsonEncode('""example""') is "\"\"example\"\"".
If you really want access to the source code of the JSON input, I'd use a non-standard JSON parser, one which allows you to access the source instead of only the parsed value.
Example:
import "package:jsontool/jsontool.dart";
/// Parses [source] as JSON, but retains source escapes in strings.
Object? readJsonSourceStrings(String source) {
return _readJson(JsonReader.fromString(source));
}
Object? _readJson(JsonReader<StringSlice> reader) {
if (reader.tryObject()) {
var map = <String, Object?>{};
while (reader.hasNextKey()) {
var keySlice = reader.nextKeySource()!;
var key = keySlice.substring(1, keySlice.length - 1);
map[key] = _readJson(reader);
}
return map;
}
if (reader.tryArray()) {
var list = <Object?>[];
while (reader.hasNext()) {
list.add(_readJson(reader));
}
return list;
}
if (reader.checkString()) {
var slice = reader.expectAnyValueSource();
return slice.substring(1, slice.length - 1);
}
return reader.tryNum() ?? reader.tryBool() ??
(reader.tryNull() ? null : (throw "Unreachable"));
}
void main() {
var m = readJsonSourceStrings(r'''{"\"\"example\"\"":"value\'"}''');
print(m); // {\"\"example\"\": value\'}
}
(Disclaimer: I wrote the jsontool package.)
Swift 3 , Xcode8.2.1,
I'm trying to extract specific values from a json file in the project. The name of the file is city.list.json, and the syntax of the json file is as follows:
{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}}
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
The input I have is the country name and i need the id value or the country code relevant returned as a string.
I get an error:
"Type 'Any?' has no subscript members",
The method I wrote:
private func findCountryCodeBy(location: String)->String{
var result:String="";
let bundle = Bundle(for: type(of: self));
if let theURL = bundle.url(forResource: "city.list", withExtension: "json") {
do {
let data = try Data(contentsOf: theURL);
if let parsedData = try? JSONSerialization.jsonObject(with: data, options:[]) as! [String:Any] {
result = parsedData["_id"][location][0] as! String;
}
} catch {
print(error);
result = "error";
}
}
return result;
}
That is not valid JSON. I think the nearest valid JSON equivalent would be EITHER a JSON list like:
[
{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}},
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
]
Ie, a list enclosed within square brackets with each item separated by a comma.
OR a JSON dictionary:
{
"707860": {"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}},
"519188": {"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
}
Ie, a dictionary enclosed within curly brackets with the key (in this case I've used your _id as the key) before the : and the value (a dictionary of all the other items" after the :.
(Newlines, tabs, whitespace are ignored, I've just included them to make it obvious what I've done).
I think that the dictionary version may suit your code better, but it depends on what else you want to do with the data. A list may suit some situations better.
I wrote a quick Python script to simply read JSON from a file (and not do anything else with it), and it produced a parsing error for the not-quite-JSON that you had, but it worked fine on both of my JSON examples, above.
NB: If you do NOT have control over the format of the file you are reading (ie, if you are receiving it from some other source which cannot produce it in any other format) then you will have to either modify the format of the file after you receiv it to make it valid JSON, OR you will have to use something other than JSONSerialization to read it. You could modify it by replacing all occurrences of }{ or }\n{ with },{ and then put [ at the beginning and ] at the end. That should do the job for converting this particular file to valid JSON for a list. Converting to a dictionary would be a little more involved.
Ideally though, you may have control over the file format yourself, in which case, just change whatever generates the file to produce correct JSON in the first place.
Once you have your valid JSON and parsed it into your parsedData variable, you'll then need to fix this line:
result = parsedData["_id"][location][0] as! String;
Assuming that location is the the equivalent of the _id string in the JSON, then you may be able to use the dictionary version of the JSON above and replace that line with something like:
result = parsedData[location]["country"];
However, if location is not the _id string in the JSON, then you'd be better off using the list version of the JSON above, and use a for loop to compare the values of each list item (or use a dictionary version of the JSON keyed on whatever location actually relates to in the JSON).
what is the difference between json string and parsed json string?
for eg in javascript suppose i have a string in the json format say [{},{}]
parsing this string will also produce the same thing.
So why do we need to parse?
It's just serialization/deserialization.
In Javscript code you normally work with the object, as that lets you easily get its properties, etc, while a JSON string doesn't do you much good.
var jsonobj = { "arr": [ 5, 2 ], "str": "foo" };
console.log(jsonobj.arr[1] + jsonobj.str);
// 2foo
var jsonstr = JSON.stringify(jsonobj);
// cannot do much with this
To send it to the server via an Ajax call, though, you need to serialize (stringify) it first. Likewise, you need to deserialize (parse) from a string into an object when receiving JSON back from the server.
Great question. The difference is transfer format.
JSON is only the 'Notation' of a JavaScript Object, it is not actually the JavaScript 'object-literal' itself. So as the data is received in JSON, it is just a string to be interpreted, evaluated, parsed, in order to become an actual JavaScript 'Object-Literal.
There is one physical difference between the two, and that is quotation marks. It makes sense, that JSON needs to be a string to be transferred. Here is how:
//A JavaScript Object-Literal
var anObj = { member: 'value'}
//A JSON representation of that object
var aJSON = { "member":"value" }
Hope that helps. All the best! Nash
I think a parsed json string should be the string data into the actual javascript objects and data arrays (or whichever language the json string contains)
The JSON object contains methods for parsing JSON and converting values to JSON.
It can't be called or constructed, and aside from its two method properties it has no interesting functionality of its own.
JSONParser parser = new JSONParser();
Object object = parser.parse(Message.toString());
JSONObject arObj = (JSONObject) object;