Flutter - Create Map from two JSON - json

I need to create a Map dictionary for this two JSON for creating a view like App Store/Play Store so, a view with cell grouped by different heading.
First JSON
[
{
"category_id":"1",
"language_code":"it",
"category_name":"punti d'interesse",
"category_description":"descrizione",
"is_hidden":"0"
},
{
"category_id":"2",
"language_code":"it",
"category_name":"farmacie",
"category_description":"desc farm",
"is_hidden":"0"
}
]
Second JSON
[
{
"poi_id":"1",
"category_id":"1",
"language_code":"it",
"poi_name":"chiese",
"poi_description":"",
"poi_image":"church.jpg"
},
{
"poi_id":"2",
"category_id":"1",
"language_code":"it",
"poi_name":"monumenti",
"poi_description":"",
"poi_image":"monument.jpg"
},
{
"poi_id":"3",
"category_id":"2",
"language_code":"it",
"poi_name":"musei",
"poi_description":"",
"poi_image":"museum.jpg"
}
]
How can I create?

Here you go:
import 'dart:convert';
void main() {
// Your first json
List<Map<String, String>> map1 = [
{
"category_id": "1",
"language_code": "it",
"category_name": "punti d'interesse",
"category_description": "descrizione",
"is_hidden": "0"
},
{
"category_id": "2",
"language_code": "it",
"category_name": "farmacie",
"category_description": "desc farm",
"is_hidden": "0"
}
];
// Your second json
List<Map<String, String>> map2 = [
{
"poi_id": "1",
"category_id": "1",
"language_code": "it",
"poi_name": "chiese",
"poi_description": "",
"poi_image": "church.jpg"
},
{
"poi_id": "2",
"category_id": "1",
"language_code": "it",
"poi_name": "monumenti",
"poi_description": "",
"poi_image": "monument.jpg"
},
{
"poi_id": "3",
"category_id": "2",
"language_code": "it",
"poi_name": "musei",
"poi_description": "",
"poi_image": "museum.jpg"
}
];
// The function that interests you (returns a map in the format you wanted)
Map<String, List> convertData(List<Map> categories, List<Map> pois) {
Map<String, List> result = {};
for (var category in categories) {
List<Map> poisOfCategory = [];
for (var poi in pois) {
if (category['category_id'] == poi['category_id']) {
poisOfCategory.add(poi);
}
}
result[category['category_name']] = poisOfCategory;
}
return result;
}
// Prints the map as a string
print(json.encode(convertData(map1, map2)));
}
The output would be:
{
"punti d'interesse":[
{
"poi_id":"1",
"category_id":"1",
"language_code":"it",
"poi_name":"chiese",
"poi_description":"",
"poi_image":"church.jpg"
},
{
"poi_id":"2",
"category_id":"1",
"language_code":"it",
"poi_name":"monumenti",
"poi_description":"",
"poi_image":"monument.jpg"
}
],
"farmacie":[
{
"poi_id":"3",
"category_id":"2",
"language_code":"it",
"poi_name":"musei",
"poi_description":"",
"poi_image":"museum.jpg"
}
]
}

Related

Parsing Iterative JSON from Firebase to Flutter

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();

Show product.length when I have JSON / OBJ / JSON / OBJ / JSON

I have this JSON
{
"StatusCode": 0,
"StatusMessage": "OK",
"StatusDescription": [
{
"_id": "12123",
"dateCreated": "2019-12-03T13:45:30.418Z",
"pharmacy_id": "011E752345553380ABC13FFA163ECD15"
"products": [
{
"productID": "1",
"quantity": 3,
"product_name": "BETADINE",
"price": 10
},
{
"productID": "2",
"quantity": 1,
"product_name": "EUCARBON",
"price": 10
}
]
},
{
"_id": "56233",
"dateCreated": "2019-12-04T09:55:21.555Z",
"pharmacy_id": "011E762345552280FBC13FFA163ECD10"
"products": [
{
"productID": "44",
"quantity": 1,
"product_name": "BETADINE",
"price": 10
}
]
}
]
}
In this JOSN I want to get length of products. For example in this I have 2 pharmacy and 5 products. I want to show 5 in my shop cart.
So I get this JSON from API with this function:
public cart: Shop[];
cartlength: number;
ngOnInit(): void {
this.shopservice.getShoppingCart().subscribe(
cart => {
this.cart = cart;
this.cartlength = cart.length;
},
err => console.error('errorrrrrrr', err),
() => console.log('error')
);
}
IN HTML:
<ActionItem ios.systemIcon="9" ios.position="left" android.position="actionBar" [text]='cartlength'></ActionItem>
Any idea please?
If cart is the array containing all the pharmacies you could use reduce method to determine the total quantity of all products for each pharmacy.
this.cartlength = this.cart.reduce((count, pharmacy) => {
count += pharmacy.products.reduce((totalQty, product) => {
return totalQty += product.quantity;
}, 0)
return count;
}, 0)

convert JavaScript nested array for priming tree format

i have following JAVASCRIPT OBJECT and i need to convert it to primeng tree format , please help
INPUT
{
"com": {
"ups": {
"demo": {
"a": 9
}
}
}
}
OUTPUT expected
[
{
"label": "COM",
"data": "COM",
"children": [{
"label": "ABC",
"data": "abc",
"children": [ "label": "x" data": "x" ,children:[]]
}]
}]
Working Example
validate(a) {
let newArr = [];
for (const key in a) {
if (key) {
newArr.push({data: key, label: key, childern: this.validate(a[key])});
}
}
return newArr;
}
const a = {
"com": {
"ups": {
"demo": {
"a": 9
}
}
}
};
console.log(this.validate(a));

How to get key from Observable?

I am trying to read data from firebase using angular 2 and typescript
my code
export class DashboardComponent implements OnInit {
itemsRef: AngularFireList<any>;
items: Observable<any[]>;
constructor( afDatabase: AngularFireDatabase) {
this.itemsRef = afDatabase.list('/user_orders/louro');
this.items = this.itemsRef.valueChanges();
this.items.subscribe(val_2 => {
alert(val_2.keys());
val_2.forEach(function (value2) {
{
Object.keys(value2).forEach(function(k2) {
{
// k is key
let count = Object.keys( (value2[k2] )).length;
console.log("New order key "+k2);
for(let i=0;i<count;i++){
console.log(i+"=> "+JSON.stringify (value2[k2][i]));
}
}
});
}
})
});
}
ngOnInit() {
}
}
and on val_2 only contains
[
{
"-L7rtl2NesdOYVD4-bMs": [
{
"ads_show": false,
"brand": "",
"buttonLabel": "Add to cart",
"child": "fruits",
"decrn": "testing for demonstrate",
"key": "-L7rtXc0pMQhi1ClK-pP",
"mid": "fresh fruits",
"note": "",
"orderInfo": {
"message": "nil",
"methode": "cash on delivery",
"status": "nil",
"time": 1521356314040,
"time2": 1521356254115
},
"p_id": 73,
"p_name": "testing",
"position": 0,
"primary_key": "testinglouro",
"qty": {
"m_qty": 1,
"qty": 23,
"unite": "1kg",
"user_intput_qty": 2
},
"quantity_new": 2,
"querykey_shop_name_top": "louro_fruits",
"sellerName": "louro",
"sellonline": true,
"seo": {
"meta_descrption": "",
"meta_title": ""
},
"service": false,
"serviceMessage": "Please enter your complaint details",
"serviceTitle": "Service Requesting",
"shopname": "louro",
"shopview": false,
"summery": "nil",
"tags": "",
"top": "fruits",
"uid": "IG2SxH6Gcabr3QVLz9jE9Wwweh62",
"variants": [
{
"img_position": 0,
"prize": {
"mrp": 58,
"selling_prize": 45,
"tax": 0
},
"qty": {
"m_qty": 1,
"qty": 23,
"unite": "1kg",
"user_intput_qty": 2
},
"shipping": {
"minmumbuy": 0,
"s_cost": 0,
"s_dlts": ""
}
}
],
"variants_position": 0
}
]
}
]
And my database is
I need this key "4X2NpohlbUa3AA7ri6iHGNm2If93" .How to get that key ? I tried val_2.key
but it showing error "[ts] Property 'key' does not exist on type 'any[]'. Did you mean 'keys'?"
In java i am using below code and work fine dataSnapshot1.getKey();
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference(getResources().getString(R.string.user_orders)+"/"+
shop_name,getContext()));
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
// MainAction.setDefaults("OpenCategories",dataSnapshot.toString(),getActivity());
if (dataSnapshot.hasChildren()) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
orderDetails1 = null;
orderDetails1 = new OrderDetails();
if (dataSnapshot1.hasChildren()) {
int id = -1;
for (DataSnapshot dataSnapshot2 : dataSnapshot1.getChildren()) {
id = id + 1;
if (dataSnapshot2.hasChildren()) {
int productid = -1;
for (DataSnapshot dataSnapshot3 : dataSnapshot2.getChildren()) {
productid = productid + 1;
if (dataSnapshot3.hasChildren()) {
orderDetails1.productmillaList.add(dataSnapshot3.getValue(Productmilla.class));
}
orderDetails1.productmillaList.get(productid).setPosition(Integer.parseInt(dataSnapshot3.getKey()));
orderDetails1.productmillaList.get(productid).setId(dataSnapshot2.getKey());
// Log.d("key2",dataSnapshot2.getKey()+" "+productid);
}
}
//orderDetails1.productmillaList.get(id).setId(dataSnapshot2.getKey());
}
}
orderDetails1.key = dataSnapshot1.getKey();
orderDetails.add(orderDetails1);
}
getaddress(orderDetails);
} else mProgressBar.setVisibility(View.GONE);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
mProgressBar.setVisibility(View.GONE);
Log.w("dd", "Failed to read value."+ error.getMessage());
}
});
Update :
According to the updated response data, you should access using Object.keys(val)[0] which gives the value for key "4X2NpohlbUa3AA7ri6iHGNm2If93", since it is the first key.
According to older response data :
Your val is an array.
This should work.
Object.keys(val[0]).forEach(function(k1) {
{
console.log("Key first : "+ k1);
});
In your JSON, val is an array.
Object.keys(val[0])
will give you the keys of the first element of that array, which is what you're after.
TO get the first key in the Object
Object.keys(val)[0]; //returns 'first key'
[https://stackoverflow.com/a/11509718/7458082][1]
To iterate through the object
Object.keys(obj).forEach(function(key,index) {
// key: the name of the object key
// index: the ordinal position of the key within the object
});
[https://stackoverflow.com/a/11509718/7458082][1]

How to access Dynamodb's original JSON elements?

I am trying to test my lambda manually with the following dynamodb event input configured in tests -
Let's call this Json-1
{
"Records": [
{
"eventID": "1",
"eventVersion": "1.0",
"dynamodb": {
"Keys": {
"Id": {
"N": "101"
}
},
"NewImage": {
"Message": {
"S": "New item!"
},
"Id": {
"N": "101"
}
},
"StreamViewType": "NEW_AND_OLD_IMAGES",
"SequenceNumber": "111",
"SizeBytes": 26
},
"awsRegion": "us-west-2",
"eventName": "INSERT",
"eventSourceARN": eventsourcearn,
"eventSource": "aws:dynamodb"
},
{
"eventID": "2",
"eventVersion": "1.0",
"dynamodb": {
"OldImage": {
"Message": {
"S": "New item!"
},
"Id": {
"N": "101"
}
},
"SequenceNumber": "222",
"Keys": {
"Id": {
"N": "101"
}
},
"SizeBytes": 59,
"NewImage": {
"Message": {
"S": "This item has changed"
},
"Id": {
"N": "101"
}
},
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"awsRegion": "us-west-2",
"eventName": "MODIFY",
"eventSourceARN": sourcearn,
"eventSource": "aws:dynamodb"
},
{
"eventID": "3",
"eventVersion": "1.0",
"dynamodb": {
"Keys": {
"Id": {
"N": "101"
}
},
"SizeBytes": 38,
"SequenceNumber": "333",
"OldImage": {
"Message": {
"S": "This item has changed"
},
"Id": {
"N": "101"
}
},
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"awsRegion": "us-west-2",
"eventName": "REMOVE",
"eventSourceARN": sourcearn,
"eventSource": "aws:dynamodb"
}
]
}
However, the json of dynamodb items look like this -
Let's call this Json-2
{
"id": {
"S": "RIGHT-aa465568-f4c8-4822-9c38-7563ae0cd37b-1131286033464633.jpg"
},
"lines": {
"L": [
{
"M": {
"points": {
"L": [
{
"L": [
{
"N": "0"
},
{
"N": "874.5625"
}
]
},
{
"L": [
{
"N": "1765.320601851852"
},
{
"N": "809.7800925925926"
}
]
},
{
"L": [
{
"N": "3264"
},
{
"N": "740.3703703703704"
}
]
}
]
},
"type": {
"S": "guard"
}
}
}
]
},
"modified": {
"N": "1483483932472"
},
"qastatus": {
"S": "reviewed"
}
}
Using the lambda function below, I can connect to my table. My goal is create a json which elastic search will accept.
#Override
public Object handleRequest(DynamodbEvent dynamodbEvent, Context context) {
List<DynamodbEvent.DynamodbStreamRecord> dynamodbStreamRecordlist = dynamodbEvent.getRecords();
DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient());
log.info("Whole event - "+dynamodbEvent.toString());
dynamodbStreamRecordlist.stream().forEach(dynamodbStreamRecord -> {
if(dynamodbStreamRecord.getEventSource().equalsIgnoreCase("aws:dynamodb")){
log.info("one record - "+dynamodbStreamRecord.getDynamodb().toString());
log.info(" getting N from new image "+dynamodbStreamRecord.getDynamodb().getNewImage().toString());
String tableName = getTableNameFromARN(dynamodbStreamRecord.getEventSourceARN());
log.info("Table name :"+tableName);
Map<String, AttributeValue> keys = dynamodbStreamRecord.getDynamodb().getKeys();
log.info(keys.toString());
AttributeValue attributeValue = keys.get("Id");
log.info("Value of N: "+attributeValue.getN());
Table table = dynamoDB.getTable(tableName);
}
});
return dynamodbEvent;
}
The format of a JSON item that elastic search expects is this and this is what I want to map the test input json to-
Let's call this Json-3
{
_index: "bar-guard",
_type: "bar-guard_type",
_id: "LEFT-b1939610-442f-4d8d-9991-3ca54685b206-1147042497459511.jpg",
_score: 1,
_source: {
#SequenceNumber: "4901800000000019495704485",
#timestamp: "2017-01-04T02:24:20.560358",
lines: [{
points: [[0,
1222.7129629629628],
[2242.8252314814818,
1254.702546296296],
[4000.0000000000005,
1276.028935185185]],
type: "barr"
}],
modified: 1483483934697,
qastatus: "reviewed",
id: "LEFT-b1939610-442f-4d8d-9991-3ca54685b206-1147042497459511.jpg"
}
},
So what I need is read Json-1 and map it to Json-3.
However, Json-1 does not seem to be complete i.e. it does not have information that a dynamodb json has - like points and lines in Json-2.
And so, I was trying to get a connection to the original table and then read this additional information of lines and points by using the ID.
I am not sure if this is the right approach. Basically, want to figure out a way to get the actual JSON that dynamodb has and not the one that has attribute types
How can I get lines and points from json-2 using java? I know we have DocumentClient in javascript but I am looking for something in java.
Also, came across a converter here but doesn't help me- https://github.com/aws/aws-sdk-js/blob/master/lib/dynamodb/converter.js
Is this something that I should use DynamoDBMapper or ScanJavaDocumentAPI for ?
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html#marshallIntoObjects-java.lang.Class-java.util.List-com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig-
If yes, I am a little lost how to do that in the code below -
ScanRequest scanRequest = new ScanRequest().withTableName(tableName);
ScanResult result = dynamoDBClient.scan(scanRequest);
for(Map<String, AttributeValue> item : result.getItems()){
AttributeValue value = item.get("lines");
if(value != null){
List<AttributeValue> values = value.getL();
for(AttributeValue value2 : values){
//what next?
}
}
}
Ok, this seems to work for me.
ScanRequest scanRequest = new ScanRequest().withTableName(tableName);
ScanResult result = dynamoDBClient.scan(scanRequest);
for(Map<String, AttributeValue> item : result.getItems()){
AttributeValue value = item.get("lines");
if(value != null){
List<AttributeValue> values = value.getL();
for(AttributeValue value2 : values){
if(value2.getM() != null)
{
Map<String, AttributeValue> map = value2.getM();
AttributeValue points = map.get("points");
List<AttributeValue> pointsvalues = points.getL();
if(!pointsvalues.isEmpty()){
for(AttributeValue valueOfPoint : pointsvalues){
List<AttributeValue> pointList = valueOfPoint.getL();
for(AttributeValue valueOfPoint2 : pointList){
}
}
}
}
}
}
}