Flutter Create dynamic widget from dynamic json response - arrays

companyList = data['fields'][0]['choices'];
if (companyList.length != 0) {
int val;
for (val = 0; val < companyList.length; val++) {
final controller = TextEditingController();
final field = xTextfield(
txtlabel: "Values",
iconfield: bookmarksIcon,
);
setState(() {
_controllers.add(controller);
_fields.add(field);
});
}
}
But this works only if json response is same when it changes and Array object is differnet i got error here is my json that will be different everytime e.g
"inputtype": "dropdown", will make a dropdown widget and all data will be put into it and so on
{ "fields": [ { "id": 31, "name": "make", "isrequired": "required", "valuetype": "text", "priority": 1, "inputtype": "dropdown", "max_min": [], "rangeable": "false", "choices": [ { "id": 46, "name": "Samsung", "categoryextrafield_id": 31, "created_at": "2021-12-29T01:30:47.000000Z", "updated_at": "2021-12-29T01:30:47.000000Z", "priority": 10 }, { "id": 47, "name": "Dell", "categoryextrafield_id": 31, "created_at": "2021-12-29T01:30:52.000000Z", "updated_at": "2021-12-29T01:30:52.000000Z", "priority": 20 }, { "id": 48, "name": "IBM", "categoryextrafield_id": 31, "created_at": "2021-12-29T01:31:09.000000Z", "updated_at": "2021-12-29T01:31:09.000000Z", "priority": 30 }, { "id": 49, "name": "Acer", "categoryextrafield_id": 31, "created_at": "2021-12-29T01:31:24.000000Z", "updated_at": "2021-12-29T01:31:24.000000Z", "priority": 40 } ], "available": [] }, { "id": 32, "name": "model", "isrequired": "required", "valuetype": "text", "priority": 2, "inputtype": "textfield", "max_min": [], "rangeable": "false", "choices": [], "available": [ { "model": "a51" }, { "model": "y9s" }, { "model": "a31" }, { "model": "yS10" }, { "model": "Y10S" }, { "model": "A551" }, { "model": "node8" }, { "model": "s9" }, { "model": null }, { "model": "2021" }, { "model": "2020" }, { "model": "2010" }, { "model": "Civic" }, { "model": "2019" }, { "model": "Daewooy9" }, { "model": "corei5" }, { "model": "corei9" }, { "model": "corei3" }, { "model": "corei11" } ] }, { "id": 29, "name": "features", "isrequired": "required", "valuetype": "text", "priority": 3, "inputtype": "checkbox", "max_min": [], "rangeable": "false", "choices": [ { "id": 41, "name": "Bluetooth", "categoryextrafield_id": 29, "created_at": "2021-12-29T01:19:00.000000Z", "updated_at": "2021-12-29T01:19:00.000000Z", "priority": 1 }, { "id": 42, "name": "Fingerprint", "categoryextrafield_id": 29, "created_at": "2021-12-29T01:19:10.000000Z", "updated_at": "2021-12-29T01:19:10.000000Z", "priority": 10 }, { "id": 43, "name": "LedDisplay", "categoryextrafield_id": 29, "created_at": "2021-12-29T01:19:35.000000Z", "updated_at": "2021-12-29T01:19:35.000000Z", "priority": 15 } ], "available": [] }, { "id": 30, "name": "condition", "isrequired": "required", "valuetype": "text", "priority": 4, "inputtype": "radiobutton", "max_min": [], "rangeable": "false", "choices": [ { "id": 44, "name": "Used", "categoryextrafield_id": 30, "created_at": "2021-12-29T01:20:31.000000Z", "updated_at": "2021-12-29T01:20:31.000000Z", "priority": 10 }, { "id": 45, "name": "New", "categoryextrafield_id": 30, "created_at": "2021-12-29T01:20:38.000000Z", "updated_at": "2021-12-29T01:20:38.000000Z", "priority": 20 } ], "available": [] } ] }

You can use the Dynamic Widget package.
Just pass the widget as JSON data from the server and use a FutureBuilder to build it when your data arrives.
You will also need to change your JSON data accordingly.

Related

How to scroll to a particular section of the data fetched from an API while filtering the data on some parameter?

I am calling an API from a server, and I am getting this as a response. A part of the data I am getting -
{
"id": 322854,
"date": "2022-09-20T18:00:00+00:00",
"time": "18:00",
"timestamp": 1663696800,
"timezone": "UTC",
"stage": null,
"week": null,
"status": {
"long": "Game Finished",
"short": "FT",
"timer": null
},
"league": {
"id": 9,
"name": "French Cup",
"type": "cup",
"season": 2022,
"logo": "https://media-2.api-sports.io/basketball/leagues/9.png"
},
"country": {
"id": 4,
"name": "France",
"code": "FR",
"flag": "https://media-2.api-sports.io/flags/fr.svg"
},
"teams": {
"home": {
"id": 22,
"name": "Boulazac",
"logo": "https://media-2.api-sports.io/basketball/teams/22.png"
},
"away": {
"id": 2294,
"name": "CEP Lorient",
"logo": "https://media-2.api-sports.io/basketball/teams/2294.png"
}
},
"scores": {
"home": {
"quarter_1": 16,
"quarter_2": 12,
"quarter_3": 21,
"quarter_4": 26,
"over_time": null,
"total": 75
},
"away": {
"quarter_1": 9,
"quarter_2": 16,
"quarter_3": 19,
"quarter_4": 23,
"over_time": null,
"total": 67
}
}
}
{
"id": 322854,
"date": "2022-09-20T18:00:00+00:00",
"time": "18:00",
"timestamp": 1663696800,
"timezone": "UTC",
"stage": null,
"week": null,
"status": {
"long": "Game Not Started",
"short": "NS",
"timer": null
},
"league": {
"id": 9,
"name": "French Cup",
"type": "cup",
"season": 2022,
"logo": "https://media-2.api-sports.io/basketball/leagues/9.png"
},
"country": {
"id": 4,
"name": "France",
"code": "FR",
"flag": "https://media-2.api-sports.io/flags/fr.svg"
},
"teams": {
"home": {
"id": 22,
"name": "Boulazac",
"logo": "https://media-2.api-sports.io/basketball/teams/22.png"
},
"away": {
"id": 2294,
"name": "CEP Lorient",
"logo": "https://media-2.api-sports.io/basketball/teams/2294.png"
}
},
"scores": {
"home": {
"quarter_1": 16,
"quarter_2": 12,
"quarter_3": 21,
"quarter_4": 26,
"over_time": null,
"total": 75
},
"away": {
"quarter_1": 9,
"quarter_2": 16,
"quarter_3": 19,
"quarter_4": 23,
"over_time": null,
"total": 67
}
}
}
There are a bunch of such objects in an array each having a different fixture. As you can see that status?.short === "NS" in one while the other is status?.short === "FT". Now, I want to filter the data using these properties.
<div className="fixturesTab-container">
<div className="fixturesTab-container__header">
<h4>Fixtures</h4>
</div>
<div className="fixturesTab-container__body">
{fixtures.map((fixture) => (
<div
key={fixture?.id}
className="fixturesTab-container__body__box"
>
......
</div>
))}
</div>
</div>
I want the data to be displayed in such a manner that when the user browse to that page and the API is being fetched, eventhough the entire data (fixtures) is being displayed in the page. I want the fixtures that have not yet started, i.e has the property of status?.short === "NS", to be displayed in the window that is visible to the user. And the rest data can be acquired by either scrolling up, which will have the fixtures that have been completed, or by scrolling down which will have the fixtures that have not yet been started.
If, I am unable to understand what I want properly, then you can check out this page . This is exactly what I am planning to achieve.

Convert array structure from first array to second

This is my multi dimensional array.
Output should be in array2 structure.
I have tried many ways covert above array in easy but all came up with bulky code and lots of iteration.
Is there any easy way to do so?
I am a new in angular and JavaScript.
var array1=[
{
"id": 1,
"name": "Johny",
"category": [
{
"id": 12,
"name": "GUI",
"status": {
"id": 123,
"status": "working",
"name": "GUI"
}
},
{
"id": 13,
"name": "GFX",
"status": {
"id": 124,
"status": "working",
"name": "GFX"
}
},
{
"id": 14,
"name": "UI",
"status": {
"id": 125,
"status": "working",
"name": "UI"
}
}
]
},
{
"id": 2,
"name": "Paul",
"category": [
{
"id": 21,
"name": "GUI",
"status": {
"id": 212,
"status": "Progress",
"name": "GUI"
}
},
{
"id": 22,
"name": "GFX",
"status": {
"id": 221,
"status": "working",
"name": "GFX"
}
},
{
"id": 23,
"name": "DM",
"status": {
"id": 231,
"status": "done",
"name": "DM"
}
}
]
}
]
I want to change into this array2.
var array2=[
{
"id": 1,
"name": "Johny",
"category": [
{
"id": 12,
"name": "GUI",
"data": [
{
"id": 12,
"name": "GUI",
"status": {
"id": 123,
"status": "working",
"name": "GUI"
}
},
{
"id": 21,
"name": "GUI",
"status": {
"id": 212,
"status": "Progress",
"name": "GUI"
}
}
]
},
{
"id": 13,
"name": "GFX",
"data": [
{
"id": 13,
"name": "GFX",
"status": {
"id": 124,
"status": "working",
"name": "GFX"
}
},
{
"id": 22,
"name": "GFX",
"status": {
"id": 221,
"status": "working",
"name": "GFX"
}
}
]
},
{
"id": 14,
"name": "UI",
"data": [
{
"id": 14,
"name": "UI",
"status": {
"id": 125,
"status": "working",
"name": "UI"
}
},
//null data if not in first
{}
]
},
{
"id": 23,
"name": "DM",
"data": [
//null data if not in first
{},
{
"id": 23,
"name": "DM",
"status": {
"id": 231,
"status": "done",
"name": "DM"
}
}
]
}
]
},
{
"id": 2,
"name": "Paul",
"category": [
{
"id": 21,
"name": "GUI",
"data": [
{
"id": 12,
"name": "GUI",
"status": {
"id": 123,
"status": "working",
"name": "GUI"
}
},
{
"id": 21,
"name": "GUI",
"status": {
"id": 212,
"status": "Progress",
"name": "GUI"
}
}
]
},
{
"id": 22,
"name": "GFX",
"data": [
{
"id": 13,
"name": "GFX",
"status": {
"id": 124,
"status": "working",
"name": "GFX"
}
},
{
"id": 22,
"name": "GFX",
"status": {
"id": 221,
"status": "working",
"name": "GFX"
}
}
]
},
{
"id": 14,
"name": "UI",
"data": [
{
"id": 14,
"name": "UI",
"status": {
"id": 125,
"status": "working",
"name": "UI"
}
},
//null data if not in first
{}
]
},
{
"id": 23,
"name": "DM",
"data": [
//null data if not in first
{},
{
"id": 23,
"name": "DM",
"status": {
"id": 231,
"status": "done",
"name": "DM"
}
}
]
}
]
}
]
Output should be in array2 structure.
Thanks in advance.
So you just want to have the original data as additional data attribute? This is simple using a forEach() loop in combination with the map() function:
array1.forEach((obj) => {
obj.category = obj.category.map((cat) => {
return {id: cat.id, name: cat.name, data: cat}
});
})
Hope this is what you're looking for :-)

Extracting an array from within an object

I have the following JSON object from which I'd like to extract a specific property
{
"gender": "male",
"age": 36,
"profession": "teacher",
"hobbies": [
{
"id": 28,
"name": "gardening"
},
{
"id": 878,
"name": "Football"
},
{
"id": 35,
"name": "Reading"
},
{
"id": 10751,
"name": "Socialising"
}
],
"Country": "Sweden",
"id": 4542236,
}
Lets say I wanted to create a new object that hold only the "hobbies" property with all the values like this
{
"hobbies": [
{
"id": 28,
"name": "gardening"
},
{
"id": 878,
"name": "Football"
},
{
"id": 35,
"name": "Reading"
},
{
"id": 10751,
"name": "Socialising"
}
]
}
Since the JSON is coming from an external API I have no control on future positioning (index) of any properties

Jq to add the element in json array conditionally and print the entire modified file

I have a json file with the below format.
I would like to add the element {"test" : "2"}in propDefs[] if the .children[].type=="environmentApprovalTask" and .children[].role.name== "GCM approver" and output that to the new file. I want the entire file with the modified content.The .children[] array may not have always 3 elements.
{
"edges": [
{
"to": "de32e562319310b7b4fe3736e22009",
"from": "99d5f0b278f08721adba7741b782d8",
"type": "SUCCESS",
"value": ""
},
{
"to": "06916609ad7fd4127815be3f075c81",
"from": "de32e562319310b7b4fe3736e22009",
"type": "SUCCESS",
"value": ""
},
{
"to": "99d5f0b278f08721adba7741b782d8",
"type": "ALWAYS",
"value": ""
}
],
"offsets": [
{
"name": "99d5f0b278f08721adba7741b782d8",
"x": -91,
"y": 100,
"h": 70,
"w": 290
},
{
"name": "06916609ad7fd4127815be3f075c81",
"x": -5,
"y": 420,
"h": 80,
"w": 120
},
{
"name": "de32e562319310b7b4fe3736e22009",
"x": 69,
"y": 240,
"h": 70,
"w": 240
}
],
"layoutMode": "manual",
"type": "graph",
"id": "d5d9c4c4-0c5f-4642-872c-ac892039eaa4",
"name": "79e8b952-dd59-4cfd-9c0c-e6c08a81d4ca",
"children": [
{
"type": "finish",
"id": "833e959c-6825-413d-afc4-7b74c0a87c3e",
"name": "06916609ad7fd4127815be3f075c81",
"children": []
},
{
"id": "e976041d-af9d-48cf-b838-735bb5efd483",
"type": "envApprovalTask",
"children": [],
"name": "de32e562319310b7b4fe3736e22009",
"roleRestrictionData": {
"contextType": "ENVIRONMENT",
"roleRestrictions": [
{
"roleId": "087175fb-5d38-42d1-b65a-2b6a6958bc21"
}
]
},
"propDefs": [{"test": "1"}],
"templateName": "ApprovalCreated",
"commentRequired": false,
"commentPrompt": "",
"role": {
"id": "087175fb-5d38-42d1-b65a-2b6a6958bc21",
"name": "Approver",
"isDeletable": true
}
},
{
"id": "513fbc6a-3c4a-4a10-9eb0-7dc893c69413",
"type": "environmentApprovalTask",
"children": [],
"name": "99d5f0b278f08721adba7741b782d8",
"roleRestrictionData": {
"contextType": "ENVIRONMENT",
"roleRestrictions": [
{
"roleId": "116b8cd5-e7e4-403d-9599-35fe25d3cba2"
}
]
},
"propDefs": [],
"templateName": "ApprovalCreated",
"commentRequired": false,
"commentPrompt": "",
"role": {
"id": "116b8cd5-e7e4-403d-9599-35fe25d3cba2",
"name": "Manager Approver",
"isDeletable": true
}
}
]
}
My final attempt with the code
cat file.json |jq '.|.children[]| select(.type=="envApprovalTask")|select(.role.name=="Approver") |.propDefs[.profDefs|length] |= .+ {"test" : "2"}'
This only produces the modified element, didnt produce the entire file as output. Please help how can i get the desired output.
TIL about complex assignments in jq. This actually works:
(.children[] | select(.type=="envApprovalTask" and .role.name=="Approver") | .propDefs) |= .+[{"test":"2"}]
The only significant difference from your version is the parenthesised left side of the assignment.

AngularJS ng-repeat display json

I'm having the hardest time figuring out how to display the following JSON file in my Angularjs repeat.
for the following JSON results, I thought I could simply display the title in an ng-repeat with the following:
<div ng-repeat="x in results">
{{x.data[0].title}}
</div>
But I'm not seeing results.
Here is the JSON:
{
"data": [
{
"id": 1,
"title": "Temp Title",
"description": "Temp Description",
"created_at": {
"date": "2016-03-15 07:10:17.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"updated_at": {
"date": "2016-03-15 07:10:17.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"user": {
"data": {
"id": 29,
"displayName": "chris.nakea",
"email": "chris.nakea#freshconsulting.com",
"join_date": 1458025279,
"profile": {
"data": {
"id": 29,
"displayName": "chris.nakea",
"avatar": null,
"firstName": null,
"lastName": null,
"bio": null,
"city": null,
"zipcode": null,
"state": null,
"country": null,
"latitude": null,
"longitude": null,
"avatars": {
"data": [
{
"id": "default_avatar.png",
"filename": "default_avatar.png",
"url": "https://cdn.band.dev/common/images/common/default_avatar.png",
"created_at": {
"date": "2016-03-15 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"images": {
"small": "https://cdn.band.dev/common/images/common/default_avatar_small.png",
"medium": "https://cdn.band.dev/common/images/common/default_avatar_medium.png",
"large": "https://cdn.band.dev/common/images/common/default_avatar_large.png"
}
}
]
},
"coverPhotos": {
"data": []
}
}
}
}
},
"category": {
"data": {
"id": 2,
"name": "Staff / Events",
"description": "Staff / Events",
"colorCode": "#242156",
"iconName": "icon-staff-events",
"iconCharacterCode": "c108"
}
},
"attachments": {
"data": [
{
"id": "1d3f96e2286c27ee599c9e49a0c33da0",
"filename": "man.jpg",
"url": "https://api.band.dev/v1/file/1d3f96e2286c27ee599c9e49a0c33da0",
"created_at": {
"date": "2016-03-15 07:10:17.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"images": {
"small": "https://api.band.dev/v1/file/50af58b3d52d8629e9f5c4d0dcdd5181",
"medium": "https://api.band.dev/v1/file/51535d38f7b3cd82313eac2414059d83",
"large": "https://api.band.dev/v1/file/a7be1dada18e4041cf48aea377cafa29"
}
}
]
}
},
{
"id": 2,
"title": "Temp Title",
"description": "Temp Description",
"created_at": {
"date": "2016-03-15 07:12:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"updated_at": {
"date": "2016-03-15 07:12:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"user": {
"data": {
"id": 29,
"displayName": "chris.nakea",
"email": "chris.nakea#freshconsulting.com",
"join_date": 1458025279,
"profile": {
"data": {
"id": 29,
"displayName": "chris.nakea",
"avatar": null,
"firstName": null,
"lastName": null,
"bio": null,
"city": null,
"zipcode": null,
"state": null,
"country": null,
"latitude": null,
"longitude": null,
"avatars": {
"data": [
{
"id": "default_avatar.png",
"filename": "default_avatar.png",
"url": "https://cdn.band.dev/common/images/common/default_avatar.png",
"created_at": {
"date": "2016-03-15 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"images": {
"small": "https://cdn.band.dev/common/images/common/default_avatar_small.png",
"medium": "https://cdn.band.dev/common/images/common/default_avatar_medium.png",
"large": "https://cdn.band.dev/common/images/common/default_avatar_large.png"
}
}
]
},
"coverPhotos": {
"data": []
}
}
}
}
},
"category": {
"data": {
"id": 2,
"name": "Staff / Events",
"description": "Staff / Events",
"colorCode": "#242156",
"iconName": "icon-staff-events",
"iconCharacterCode": "c108"
}
},
"attachments": {
"data": [
{
"id": "a93cf8df7b60686e7ca6884d0ce353c8",
"filename": "man2.jpg",
"url": "https://api.band.dev/v1/file/a93cf8df7b60686e7ca6884d0ce353c8",
"created_at": {
"date": "2016-03-15 07:12:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"images": {
"small": "https://api.band.dev/v1/file/cd04551395a355f4792fb85833156741",
"medium": "https://api.band.dev/v1/file/4ff543cd8f5055bfecd703dedaee6d87",
"large": "https://api.band.dev/v1/file/5cdd9a0c3650228e0b93f9c6cd1404df"
}
}
]
}
}
]
}
You can just remove the datap[0] part and get the output
<div ng-repeat="x in results.data">
{{x.title}}
</div>
Output:
Temp Title
Temp Title
if you want to filter then you can do it by
<div ng-repeat="x in results.data | filter: { id: '1' }">
{{x.title}}
</div>
Output:
Temp Title
<div ng-repeat="item in data">{{item.title}}</div>
And in your controller, bind the json to the scope.
$scope.data = jsonData.data;
Here's a fiddle for you - jsFiddle
<div ng-repeat="x in results.data">
{{x.title}}
</div>
https://jsfiddle.net/nvqf8oo7/6/
Thank you all for responding. I finally figured out that the reason I wasn't seeing anything was because I am using ui.bootstrap's modal and I was out of scope.
I resolved this by moving the ng-repeat out of the modal, but I could have also tried to work with the modal scope itself.

Resources