Iterating through JSON map in Dart - dart

This may be a fundamental question but I'm trying to calculate tax from the JSON data below. However, I get this message every time I try to print the result.
Uncaught Error: TypeError: Instance of 'JsLinkedHashMap<String, Object>': type 'JsLinkedHashMap<String, Object>' is not a subtype of type 'int'
void main() {
double tax = 0.0;
int index = 0;
Map<String, dynamic> test = {
"data": {
"cartItem": [
{
"id": 30,
"productName": "Mango",
"price": 100.0,
"tax": 10.0,
"quantity": 7,
"mainImage": "http://3.109.206.91:8000/static/product_module/product/png-clipart-slice-of-mango-mango-tea-fruit-mango-game-food_HSPnZGK.png",
"totalPrice": 700.0
}
],
"grandTotal": 700.0
}
};
for(index in test['data']['cartItem']) {
tax += (test['data']['cartItem'][index]['tax'] / 100.0);
}
print(tax);
}
The reason behind running a loop is that there may be more than one object inside the data list.

Your code is incorrect.
void main() {
double tax = 0.0;
int index = 0;
Map<String, dynamic> test = {
"data": {
"cartItem": [
{
"id": 30,
"productName": "Mango",
"price": 10.0,
"tax": 10.0,
"quantity": 7,
"mainImage":
"http://3.109.206.91:8000/static/product_module/product/png-clipart-slice-of-mango-mango-tea-fruit-mango-game-food_HSPnZGK.png",
"totalPrice": 700.0
}
],
"grandTotal": 700.0
}
};
for (final cartItem in test['data']['cartItem']) {
tax += (cartItem['tax'] as num) / 100.0;
}
print(tax);
}

Related

How to deserialize a json object into rust understandable code using enums?

I need to deserialize ( and later on serialize ) a piece of data that has this type of a structure :
{
"type": "TypeApplication",
"val": {
"con": {
"type": "TypeConstructor",
"val": [
"Builtin",
"Record"
]
},
"arg": {
"type": "RowCons",
"val": {
"label": "953e3dd6-826e-1985-cb99-fd4ed4da754e",
"type": {
"type": "TypeApplication",
"val": {
"con": {
"type": "TypeConstructor",
"val": [
"Builtin",
"List"
]
},
"arg": {
"type": "Element",
"meta": {
"multiLine": true
}
}
},
"system": {
"label": "nullam-senectus-port - Text",
"isBindable": true,
"defaultValue": [
{
"id": "4a05486f-f24d-45f8-ae13-ab05f824d74d",
"type": "String",
"pluginType": "Basic",
"data": {
"value": "Nullam senectus porttitor in eget. Eget rutrum leo interdum."
},
"children": [],
"text": true
}
],
"isUnlinked": false,
"isDefault": false
}
},
"tail": {
"type": "RowCons",
"val": {
"label": "94f603df-d585-b45a-4252-9ec77cf5b13c",
"type": {
"type": "TypeApplication",
"val": {
"con": {
"type": "TypeConstructor",
"val": [
"Builtin",
"List"
]
},
"arg": {
"type": "Element",
"meta": {
"multiLine": true
}
}
},
"system": {
"label": "best-services - Text",
"isBindable": true,
"defaultValue": [
{
"id": "6265ca45-3f69-4844-97e2-c05bbfb9fee5",
"type": "String",
"pluginType": "Basic",
"data": {
"value": "Best Services"
},
"children": [],
"text": true
}
]
}
},
"tail": {
"type": "RowEmpty"
}
}
}
}
}
}
}
I do not know what this data exactly is, but I know this is trying to represent a function/element that takes in values and defaults for those values as parameters/properties.
I want to deserialize it using serde and consequently serialize it too.
I have so far been able to write something that sort of works but not really :
#[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(tag = "type", content = "val")]
pub enum WebflowPropDataType {
TypeApplication {
con: Box<WebflowPropDataType>, // Normally Passes the Type Constructor
arg: Box<WebflowPropDataType>, // Normally Passes the Row Constructor
},
TypeConstructor(Vec<String>), // Stores Value of TypeConstructor
RowCons {
label: String, // Stores the label of the Row
#[serde(rename = "type")]
row_con_type: Box<WebflowPropDataType>, // Stores the type of the Row
tail: Box<WebflowPropDataType>,
},
RowEmpty, // For Ending the recursive usage of rowConstructor
}
#[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct WebflowRowConDataType {
#[serde(rename = "type")]
val_type: String, // TypeApplication
val: Box<WebflowPropDataType>,
}
This works for a structure like this :
{
"type": "TypeApplication",
"val":{
"con": {
"type": "TypeConstructor",
"val": []
},
"arg": {
"type": "RowEmpty"
}
}
}
but would fail if I try to work with initial example. I know this may be due to the lack of a proper arg type or maybe even the TypeApplication Enum hand is malformed.
I do see that a adjancent typing solution would be enough for most of the times but there are cases as seen in the example structure that there is a third value called system and I am unable to determine what type of approach would help me achieve this type of outcome.
How should I approach this problem in order to generate this type of code.
I am not asking anyone to write me a solution but to give me suggestion as to what my approach should be? Whether you'd know what type of data this is/how to generated this , or even if there are some other library I should look into to manipulate this type of data or maybe look at other approaches.
PS : - My end goal is to be able to generate / serialize this type of JSON code from already contained knowledge of properties and default values of a function/object.
Here are my recommendations:
Use just #[serde(tag = "type")] instead of #[serde(tag = "type", content = "val")]. You will have to handle val manually (extracting the current enum members into separate structs), but this allows you to also handle TypeApplication.system and Element.meta.
This also has the small benefit of reducing the amount of Boxes involved.
Consider whether all of the different cases in WebflowPropDataType can actually occur everywhere it's used. If not (maybe Element can only happen under TypeApplication.val.arg), then you may want to split the enum into multiple so that this is reflected in the type system.
Example for #1:
use serde::{Serialize, Deserialize};
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TypeApplicationVal {
con: WebflowPropDataType, // Normally Passes the Type Constructor
arg: WebflowPropDataType, // Normally Passes the Row Constructor
}
// #[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TypeApplicationSystem {
label: String,
#[serde(rename = "isBindable")]
is_bindable: bool,
// TODO: defaultValue
#[serde(rename = "isUnlinked")]
#[serde(skip_serializing_if = "Option::is_none")]
is_unlinked: Option<bool>,
#[serde(rename = "isDefault")]
#[serde(skip_serializing_if = "Option::is_none")]
is_default: Option<bool>,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct RowConsVal {
label: String, // Stores the label of the Row
#[serde(rename = "type")]
typ: WebflowPropDataType, // Stores the type of the Row
tail: WebflowPropDataType,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ElementMeta {
#[serde(rename = "multiLine")]
multi_line: bool,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(tag = "type")]
pub enum WebflowPropDataType {
TypeApplication {
val: Box<TypeApplicationVal>,
#[serde(skip_serializing_if = "Option::is_none")]
system: Option<TypeApplicationSystem>,
},
TypeConstructor {
val: Vec<String> // Stores Value of TypeConstructor
},
RowCons {
val: Box<RowConsVal>,
},
Element {
meta: ElementMeta,
},
RowEmpty, // For Ending the recursive usage of rowConstructor
}
playground

needs to convert Lists of map data into One map

My question is about dart....
the result I got
[{'sam': 8}, {'john': 822}]
I need to convert it into like below
{'sam': 8, 'john': 822}
pls help me.
thanks for reading
Something like this?
void main() {
final listOfMaps = [
{'sam': 8},
{'john': 822},
];
final map = {for (final map in listOfMaps) ...map};
print(map); // {sam: 8, john: 822}
}
Update after example of data has been uploaded
I have made the following example which parses the input you have posted as returns the expected data:
void main() {
final map = {
for (final map in someListOfMaps)
for (final voted in map['voted']! as List<Map<String, String>>)
for (final vote in voted.entries) vote.key: int.parse(vote.value)
};
print(map);
// {60e6956078fb6f42da: 1, 60e6956020d8bf42db: 5, 120d8bf42dffsww66: 1, jd58466daa4dw2: 20, gg4c577x6ad8ds6a: 6}
}
const someListOfMaps = [
{
"voted": [
{"60e6956078fb6f42da": "1"},
{"60e6956020d8bf42db": "5"}
],
"_id": "60e698fe78fb6120d8bf42dd",
"name": "donald"
},
{
"voted": [
{"120d8bf42dffsww66": "1"}
],
"_id": "60e698fe78fb6120d8bf42de",
"name": "barrack"
},
{
"voted": [
{"jd58466daa4dw2": "20"}
],
"_id": "60e698fe78fb6120d8bf42df",
"name": "malan"
},
{
"voted": [
{"gg4c577x6ad8ds6a": "6"}
],
"_id": "60e698fe78fb6120d8bf42e0",
"name": "kuma"
}
];
This is a longer approach and probably more understandable.
// the result I got [{'sam': 8}, {'john': 822}]
// I need to convert it into like below {'sam': 8, 'john': 822}
void main() {
final mapList = [{'sam': 8}, {'john': 822}];
print(mapListToJustMap(mapList)); // output: {sam: 8, john: 822}
// The <int> is not required
print(genericMapListToJustMap<int>(mapList)); // output: {sam: 8, john: 822}
}
Map<String, int> mapListToJustMap(List<Map<String, int>> mapList) {
// Create a new empty map object
final newMap = <String, int>{};
// Iterate through the mapList input
for (final singleMap in mapList) {
// add the current iteration to the new map object
newMap.addAll(singleMap);
}
return newMap;
}
// A generic approach
Map<String, T> genericMapListToJustMap<T>(List<Map<String, T>> mapList) {
// Create a new empty map object
final newMap = <String, T>{};
// Iterate through the mapList input
for (final singleMap in mapList) {
// add the current iteration to the new map object
newMap.addAll(singleMap);
}
return newMap;
}

How to convert List<List<Map<String, String>>> into List<List<CustomObject>> in dart

I want to convert a List<List<Map<String, String>>> into List<List> a custom class, how to achieve this in dart.
How to convert this
List<List<Map<String, String>>> = [
{
"course_name": "Estimation & Quantity Surveying",
"credit": "4",
"hours": "40",
},
{
"course_name": "IDP - Industrial Design Project phase II",
"credit": "4",
"hours": "40",
}
],
[
{
"course_name": "Data Base Management System",
"credit": "4",
"hours": "40",
},
{
"course_name": "Estimation & Quantity Surveying",
"credit": "4",
"hours": "40",
},
],
];
into
List<List<StudentTimeTable>>
This is my custom class
class StudentTimeTable{
final String courseName;
final String credit;
final String hours;
}
Something like this would do the trick:
class StudentTimeTable {
final String courseName;
final String credit;
final String hours;
StudentTimeTable.fromMap(Map<String, String> map)
: courseName = map['course_name'],
credit = map['credit'],
hours = map['hours'];
#override
String toString() =>
'StudentTimeTable(courseName = $courseName, credit = $credit, hours = $hours)';
}
void main() {
List<List<Map<String, String>>> input = [
[
{
"course_name": "Estimation & Quantity Surveying",
"credit": "4",
"hours": "40",
},
{
"course_name": "IDP - Industrial Design Project phase II",
"credit": "4",
"hours": "40",
}
],
[
{
"course_name": "Data Base Management System",
"credit": "4",
"hours": "40",
},
{
"course_name": "Estimation & Quantity Surveying",
"credit": "4",
"hours": "40",
},
],
];
List<List<StudentTimeTable>> output = [
...input.map(
(subList) => [...subList.map((map) => StudentTimeTable.fromMap(map))])
];
output.forEach(print);
// [StudentTimeTable(courseName = Estimation & Quantity Surveying, credit = 4, hours = 40), StudentTimeTable(courseName = IDP - Industrial Design Project phase II, credit = 4, hours = 40)]
// [StudentTimeTable(courseName = Data Base Management System, credit = 4, hours = 40), StudentTimeTable(courseName = Estimation & Quantity Surveying, credit = 4, hours = 40)]
}
Explanation of what going on!
The solution makes use of "spread operator" which you can read more about here:
https://dart.dev/guides/language/language-tour#spread-operator
In shot, it is a easy way to create a new list and take all elements in an iterable and put into the list.
So lets see what I do:
List<List<StudentTimeTable>> output = [...input.map((subList) => ...)]
Here we define a new list which are filled with the elements from input.map. The map method are used to take each element in the input and convert it to something else. In our case we want to convert each element in our input (which are also a List) from List<Map<String, String>> to List<StudentTimeTable>
We are then mapping each List<Map<String, String>> to the value from this:
[...subList.map((map) => StudentTimeTable.fromMap(map))]
Which returns a list filled with the elements from the iterator returned from subList.map. The purpose of this map is to convert Map<String, String> into StudentTimeTable.
This is done by calling our new constructor which takes a Map<String, String>:
StudentTimeTable.fromMap(Map<String, String> map)
: courseName = map['course_name'],
credit = map['credit'],
hours = map['hours'];
The same code could have been written something like this which is properly easier to read:
final output = <List<StudentTimeTable>>[];
for (final sublist in input) {
final studentTimeTableSubList = <StudentTimeTable>[];
for (final map in sublist) {
studentTimeTableSubList.add(StudentTimeTable.fromMap(map));
}
output.add(studentTimeTableSubList);
}
And a third way would be something like this which uses "collection for" from the same link about "spread operator":
final output = [
for (final sublist in input)
[for (final map in sublist) StudentTimeTable.fromMap(map)]
];

How do I implement vaadin-grid-tree-column in polymer 3

I have the following in the application template:
<vaadin-grid id="directory">
<vaadin-grid-tree-column path="name" header="Name"></vaadin-grid-tree-column>
</vaadin-grid>
The iron-ajax calls the following on a successful response:
getlist(request) {
var myResponse = request.detail.response;
console.log(myResponse);
this.$.directory.items = myResponse;
}
The data that is returned is:
[
{
"name": "apps",
"fullpath": "/db/system/xqdoc/apps",
"children": [
{
"name": "xqDoc",
"fullpath": "/db/system/xqdoc/apps/xqDoc",
"children": [
{
"name": "modules",
"fullpath": "/db/system/xqdoc/apps/xqDoc/modules",
"children": [
{
"name": "config.xqm.xml",
"fullpath": "/db/system/xqdoc/apps/xqDoc/modules/config.xqm.xml"
},
{
"name": "xqdoc-lib.xqy.xml",
"fullpath": "/db/system/xqdoc/apps/xqDoc/modules/xqdoc-lib.xqy.xml"
}
]
}
]
}
]
}
]
The apps shows up, but when I expand the apps node, then xqDoc node doees not show up.
Do I need additional data in the dataset?
Am I missing some coding that is needed?
I have the solution.
<vaadin-grid id="directory" selected-items="{{selected}}">
<vaadin-grid-tree-column path="name" header="Name"item-has-children-path="hasChildren"></vaadin-grid-tree-column>
</vaadin-grid>
I setup the provider using the connectedCallback and not to use an iron-ajax for talking with the server.
connectedCallback() {
super.connectedCallback();
const grid = this.$.directory;
this.$.directory.dataProvider = function(params, callback) {
let url = "/exist/restxq/xqdoc/level" +
'?page=' + params.page + // the requested page index
'&per_page=' + params.pageSize; // number of items on the page
if (params.parentItem) {
url += '&path=' + params.parentItem.fullpath;
}
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var response = JSON.parse(xhr.responseText);
callback(
response.data, // requested page of items
response.totalSize // total number of items
);
};
xhr.open('GET', url, true);
xhr.send();
};
this.$.directory.addEventListener('active-item-changed', function(event) {
const item = event.detail.value;
if (item && item.hasChildren == false) {
grid.selectedItems = [item];
} else {
grid.selectedItems = [];
}
});
}
The web service returns a level of the tree:
{
"totalSize": 2,
"data": [
{
"name": "apps",
"fullpath": "/apps",
"hasChildren": true
},
{
"name": "lib",
"fullpath": "/lib",
"hasChildren": true
}
]
}
The codebase is here: https://github.com/lcahlander/xqDoc-eXist-db

Post method with multiple parameter

I am unable to insert multiple rows in database using Post method in MVC web API. I have written code for it but when i am testing by inserting multiple rows through postman it is giving error. At line first the variable "delegatetable" shows null due to which error is coming. i am not doing database connection through entity framework, i have created a DelegateTable class.
public HttpResponseMessage Post(List<DelegateTable> delegatetable)
{
try
{
using (var delegateContext = new ShowContext())
{
foreach (DelegateTable item in delegatetable)
{
DelegateTable delegates = new DelegateTable();
delegates.Salutation__c = item.Salutation__c;
delegates.First_Name__c = item.First_Name__c;
delegates.Last_Name__c = item.Last_Name__c;
delegates.Account_Name__c = item.Account_Name__c;
delegates.Contact_Email__c = item.Contact_Email__c;
delegates.Category__c = item.Category__c;
delegates.Conference_Type__c = item.Conference_Type__c;
delegates.Conference_Selection__c = item.Conference_Selection__c;
delegates.Payment_Statuss__c = item.Payment_Statuss__c;
delegates.Barcode__c = item.Barcode__c;
delegateContext.SaveChanges();
}
var message = Request.CreateResponse(HttpStatusCode.Created, delegatetable);
message.Headers.Location = new Uri(Request.RequestUri.ToString());
return message;
}
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
Json data that i am passing is below
[
{
"attributes": {
"type": "Registration__c",
"url": "/services/data/v43.0/sobjects/Registration__c/a3h8E0000009VuVQAU"
},
"Salutation__c": "Dr.",
"First_Name__c": "Test",
"Last_Name__c": "Test",
"Account_Name__c": "Test",
"Contact_Email__c": "test123#gmail.com",
"Category__c": "Test",
"Conference_Type__c": null,
"Conference_Selection__c": null,
"Payment_Statuss__c": null,
"Barcode__c": "Test"
},
{
"attributes": {
"type": "Registration__c",
"url": "/services/data/v43.0/sobjects/Registration__c/a3hD0000001kEfOIAU"
},
"Salutation__c": "Mr.",
"First_Name__c": "Demo",
"Last_Name__c": "Demo",
"Account_Name__c": "Demo",
"Contact_Email__c": "Demo#gmail.com",
"Category__c": "Demo",
"Conference_Type__c": null,
"Conference_Selection__c": null,
"Payment_Statuss__c": null,
"Barcode__c": null
}
]
You may try to reformat your payload as a JSON array, as the problem might be that the payload cannot be converted to a List.
Try this:
{
"delegates" :
[
{
"attributes": ..., ...
},
{ "attributes": ..., ...
},
...
]
}

Resources