I found an example of JSON serialization and deserialization to objects in Flutter
but how to do that with a list of persons like:
[
{
"name": "John",
"age": 30,
"cars": [
{
"name": "BMW",
"models": [
"320",
"X3",
"X5"
]
}
]
},
{
"name": "John",
"age": 30,
"cars": [
{
"name": "Ford",
"models": [
"Fiesta",
"Focus",
"Mustang"
]
}
]
}
]
When I call _person = serializers.deserializeWith(Person.serializer, JSON.decode(json)); I get this error:
The following _CastError was thrown attaching to the render tree:
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String' in type cast where
_InternalLinkedHashMap is from dart:collection
String is from dart:core
String is from dart:core
I created a surrounding Persons class:
abstract class Persons implements Built<Persons, PersonsBuilder> {
BuiltList<Person> get persons;
Persons._();
factory Persons([updates(PersonsBuilder b)]) = _$Persons;
static Serializer<Persons> get serializer => _$personsSerializer;
}
and call _person = serializers.deserializeWith(Persons.serializer, JSON.decode(json)); but the error is the same.
How to (de-)serialize a Json list of objects?
Instead of
_person = serializers.deserializeWith(Person.serializer, JSON.decode(json));
Try
_person = serializers.deserializeWith(Person.serializer, (JSON.decode(json) as List).first);
Or
var personList = (JSON.decode(json) as List).map((j) => serializers.deserializeWith(Person.serializer, j)).toList();
Related
I'm trying to parse a given JSON string and abstract some fields from it.
my Test method looks like this
Steps followed
Making a rest api call and getting response using restassured
response is stored in Response object from restassured
From response ResponseBody is being extracted using getBody() method in ResponseBody object
ResponseBody object is being converted to string using asString()
JsonPath object is being created from string value
Json is parsed by providing Jway Expression
#Test
Response searchResult = this.getEndPoint().SearchRecallAgreement(payload);
ResponseBody b = searchResult.getBody();
String responseBody = b.asString();
JsonPath j = new JsonPath(responseBody);
List<String> ls = j.getList("payload.returnTerms[*].returnTermPolicies[?(#.policyType == 'RC_ITEMS_POLICY')].policies[?(#.policyKey=='/575330172')].policyKey");
System.out.println(ls);
Error in console
Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script1.groovy: 1: Unexpected input: '['; Expecting <EOF> # line 1, column 46.
RootObject.payload.returnTerms[*].return
Json string looks like
{
"status": "OK",
"header": {
"headerAttributes": {}
},
"errors": [],
"payload": {
"totalCount": 6,
"returnTerms": [
{
"returnTermType": "RECALL_AGREEMENT",
"returnTermPolicies": [
{
"policyType": "RC_ITEMS_POLICY",
"keyTemplate": "/itemNo/storeNo",
"policies": [
{
"policyKey": "/583919815",
"attributeList": [
]
},
{
"policyKey": "/575330172",
"attributeList": [
]
},
{
"policyKey": "/583919815/2345"
}
]
}
]
},
{
"returnTermPolicies": [
{
"policyType": "RC_ITEMS_POLICY",
"keyTemplate": "/itemNo/storeNo",
"policies": [
{
"policyKey": "/583919815",
"attributeList": [
]
},
{
"policyKey": "/575330172",
"attributeList": [
]
},
{
"policyKey": "/583919815/2346"
},
{
"policyKey": "/583919815/2345"
}
]
}
]
}
]
}
}
Expected output :
[
"/575330172",
"/575330172"
]
I have data saved into Realtime Firebase as an iterative JSON as shown in the picture.
Realtime Firebase data
[
{
"name": "Math",
"subMenu": [
{
"name": "Math1",
"subMenu": [
{
"name": "Math 1.1"
},
{
"name": "Math 1.2",
"subMenu": [
{
"name": "Math 1.2.1",
"subMenu": [
{
"name": "Math 1.2.1.1"
},
{
"name": "Math 1.2.1.2"
}
]
},
{
"name": "Math 1.2.2"
}
]
}
]
},
{
"name": "Math2"
},
{
"name": "Math3",
"subMenu": [
{
"name": "Math 1.3.1"
},
{
"name": "Math 1.3.2"
}
]
}
]
},
{
"name": "Marketing",
"subMenu": [
{
"name": "Promotions",
"subMenu": [
{
"name": "Catalog Price Rule"
},
{
"name": "Cart Price Rules"
}
]
},
{
"name": "Communications",
"subMenu": [
{
"name": "Newsletter Subscribers"
}
]
}
]
}
]
How the JSON look like in Realtime Firebase
'Click the image'
datamodel.dart
class Menu {
String? name;
int? font;
List<Menu>? subMenu = [];
Menu({this.name, this.subMenu, this.font});
Menu.fromJson(Map<String, dynamic> json) {
font = json['font'];
name = json['name'];
if (json['subMenu'] != null) {
json['subMenu'].forEach((v) {
subMenu?.add(Menu.fromJson(v));
});
}
}
}
My goal is to build a multilevel list view in Flutter that reflexes iterative JSON structure. So, I implemented a method that returns List<Menu>, and then pass it to a Futurebuilder to build a multilevel list View.
The method.
final ref = FirebaseDatabase.instance.ref();
Future<List<Menu>> firebaseCalls(DatabaseReference ref) async {
final snapshot = await ref.child('Task').get();
final jsondata = snapshot.value as Map<String, dynamic>;
final list = json.decode(jsondata) as List<dynamic>; // Error Location
return list.map((e) => Menu.fromJson(e)).toList();
}
and I got the following
The Error
error: The argument type 'Map<String, dynamic>' can't be assigned to the parameter type 'String'. (argument_type_not_assignable at [flutter_multilevel_list_from_json] lib\main.dart:28)
tried to change the list type to List<dynamic> but still give me an error.
json.decode() takes a String as input, and you are passing a Map<String,dynamic> into it.
That is your problem, not that you are trying to cast it to a List<dynamic>
May be this will be helpful (jsondata as List).map((e) => Menu.fromJson(e)).toList();
My apache beam application receives a message in JSON array but insert each row to a BigQuery table. How can I support this usecase in ApacheBeam? Can I split each row and insert it to table one by one?
JSON message example:
[
{"id": 1, "name": "post1", "price": 10},
{"id": 2, "name": "post2", "price": 20},
{"id": 3, "name": "post3", "price": 30}
]
BigQuery table schema:
[
{
"mode": "REQUIRED",
"name": "id",
"type": "INT64"
},
{
"mode": "REQUIRED",
"name": "name",
"type": "STRING"
},
{
"mode": "REQUIRED",
"name": "price",
"type": "INT64"
}
]
Here is my solution. I converted JSON string to List once then c.output one by one. My code in in Scala but you can do the same thing in Java.
case class MyTranscationRecord(id: String, name: String, price: Int)
case class MyTranscation(recordList: List[MyTranscationRecord])
class ConvertJSONTextToMyRecord extends DoFn[KafkaRecord[java.lang.Long, String], MyTranscation]() {
private val logger: Logger = LoggerFactory.getLogger(classOf[ConvertJSONTextToMyRecord])
#ProcessElement
def processElement(c: ProcessContext): Unit = {
try {
val mapper: ObjectMapper = new ObjectMapper()
.registerModule(DefaultScalaModule)
val messageText = c.element.getKV.getValue
val transaction: MyRecord = mapper.readValue(messageText, classOf[MyTranscation])
logger.info(s"successfully converted to an EPC transaction = $transaction")
for (record <- transaction.recordList) {
c.output(record)
}
} catch {
case e: Exception =>
val message = e.getLocalizedMessage + e.getStackTrace
logger.error(message)
}
}
}
im trying to extract my data from json into a case class without success.
the Json file:
[
{
"name": "bb",
"loc": "sss",
"elements": [
{
"name": "name1",
"loc": "firstHere",
"elements": []
}
]
},
{
"name": "ca",
"loc": "sss",
"elements": []
}
]
my code :
case class ElementContainer(name : String, location : String,elements : Seq[ElementContainer])
object elementsFormatter {
implicit val elementFormatter = Json.format[ElementContainer]
}
object Applicationss extends App {
val el = new ElementContainer("name1", "firstHere", Seq.empty)
val el1Cont = new ElementContainer("bb","sss", Seq(el))
val source:String=Source.fromFile("src/bin/elementsTree.json").getLines.mkString
val jsonFormat = Json.parse(source)
val r1= Json.fromJson[ElementContainer](jsonFormat)
}
after running this im getting inside r1:
JsError(List((/elements,List(ValidationError(List(error.path.missing),WrappedArray()))), (/name,List(ValidationError(List(error.path.missing),WrappedArray()))), (/location,List(ValidationError(List(error.path.missing),WrappedArray())))))
been trying to extract this data forever, please advise
You have location instead loc and, you'll need to parse file into a Seq[ElementContainer], since it's an array, not a single ElementContainer:
Json.fromJson[Seq[ElementContainer]](jsonFormat)
Also, you have the validate method that will return you either errors or parsed json object..
For a given JSON how do I get the _id to use it as an id for inserting in another JSON?
Tried to get the ID as shown below but does not return correct results.
private def getModelRunId(): List[String] = {
val resultsCursor: List[DBObject] =
modelRunResultsCollection.find(MongoDBObject.empty, MongoDBObject(FIELD_ID -> 1)).toList
println("resultsCursor >>>>>>>>>>>>>>>>>> " + resultsCursor)
resultsCursor.map(x => (Json.parse(x.toString()) \ FIELD_ID).asOpt[String]).flatten
}
{
"_id": ObjectId("5269723bd516ec3a69f3639e"),
"modelRunId": ObjectId("5269723ad516ec3a69f3639d"),
"results": [
{
"ClaimId": "526971f5b5b8b9148404623a",
"pricingResult": {
"TxId": 0,
"ClaimId": "Large_Batch_1",
"Errors": [
],
"Disposition": [
{
"GroupId": 1,
"PriceAmt": 20,
"Status": "Priced Successfully",
"ReasonCode": 0,
"Reason": "RmbModel(PAM_DC_1):ProgramNode(Validation CPG):ServiceGroupNode(Medical Services):RmbTerm(RT)",
"PricingMethodologyId": 2,
"Lines": [
{
"Id": 1
}
]
}
]
}
},
If you want to find objectId's:
import com.mongodb.casbah.Imports._
collection.find(MongoDBObject(/*query*/)).map(_._id)
If you want to query by id:
collection.findOneByID(/*id*/)
I suppose you are using Casbah, the official Driver for Scala.
You just need to modify the map function :
resultsCursor.map { x => x.as[org.bson.types.ObjectId](FIELD_ID)}
Casbah does the deserialization from BSON to Scala object, so you don't have to do it yourself !