How to get the value without "index" in Flutter - flutter

How to get an average number of star (means result should get 1.5) ?
Note: The value to get is without index because it is not under ListView.builder
Below is the sample json code and this is how what i tried till now.
JSON
{
"message": "feedbacks for restaurant branch returened",
"data": [
{
"id": "4",
"comment": "Investor Operations Coordinator",
"star": 1,
}
{
"id": "4",
"comment": "Investor Operations Coordinator",
"star": 2,
}
]
}
DART
Widget buildReviewNumbers(List<FeedbacksData> data) {
return Column(
children: [
for (int index = 0; index < data.length; index++)
Text(
data[index].star.toString(),
style: TextStyle(fontWeight: FontWeight.w900, fontSize: 30.0),
),
],
);
}

paste it on DartPad
final map = {
"message": "feedbacks for restaurant branch returened",
"data": [
{
"id": "4",
"comment": "Investor Operations Coordinator",
"star": 1,
},
{
"id": "4",
"comment": "Investor Operations Coordinator",
"star": 2,
}
]
};
void main() {
final data = map['data'] as List<Map<String, dynamic>>;
var total = 0;
data.forEach((e) {
total += e['star'] as int;
});
print(total/ data.length);
}
For your case:
Widget buildReviewNumbers(List<FeedbacksData> data) {
var total = 0;
data.forEach((e) {
total += e.star;
});
return Text(
'${total/data.length}',
style: TextStyle(fontWeight: FontWeight.w900, fontSize:30.0),
);
}

Your jsondata of type Map dynamic has to be converted to a list of Feedbacks according to your code. Once done just use the map operator to loop through your data.
Column(
children: data.map((item) => Text(item.star.toString())).toList();
);
For lack of more info on what Feedbacks data looks like i shortened it to this.

You can use reduce to get the total value of ratings, then divide it by the number of ratings. See the concrete example on DartPad.

Related

add label in dropdown item but MUST depends other variable (FLUTTER)

List<Map<String, dynamic>> category = [
{
"name": "One",
"detail": ['11', '12', '13', '14'],
"department": "aaa",
},
{
"name": "two",
"detail": ['21', '22', '23', '24'],
"department": "bbb",
},
{
"name": "three",
"detail": ['31', '32', '33', '34'],
"department": "ccc",
},
{
"name": "four",
"detail": ['41', '42', '43', '44'],
"department": "aaa",
},
{
"name": "five",
"detail": ['41', '42', '43', '44'],
"department": "aaa",
},
];
for (final item in category) {
if (item["department"] == "aaa") {
for (final value in item.values) {
if (value is List) {
for (final listValue in value) {
data.add({'value': listValue, 'bold': false});
}
} else {
data.add({'value': item['department'], 'bold': true});
}
}
}
}
I have used the above (loop) method to doing the dropdown, but the category "name" will repeat many times, as shown in first picture
May I know how to make the list category be like the second picture dropdown, for example, the name will be the label, detail will be item of the label. Lastly, the 'department' is for classify showing which data, let say I want to show the data that department is 'aaa' means that 3 list data will be shown in the dropdown item.
Looking at your data named as "category" which is a list of Maps, I think you can add labels and achieve the required functionality that includes using custom variable in the following way:
const dept = 'aaa';
final data = category.where((element) => element['department'] == dept);
List<DropdownMenuItem<String>>? get_items() {
final List<DropdownMenuItem<String>> _dropdownItems1 = [];
for (final val in data) {
for (final value in val.values) {
if (value is List) {
for (final listValue in value) {
_dropdownItems1.add(
DropdownMenuItem(
child: Text(listValue),
value: listValue,
),
);
}
} else if (value != dept) {
_dropdownItems1.add(DropdownMenuItem(
child:
Text(value, style: const TextStyle(fontWeight: FontWeight.bold)),
value: value,
));
}
}
}
return _dropdownItems1;
}
Now, in the dropdownbutton you can simply call "get_items()" to get the dropdown menu items for creating the dropdown menu.
It can be done as mentioned in the code below.
DropdownButton<String>(
value: selectedItem,
items: get_items(),
onChanged: (value) {
setState(() {
selectedItem = value;
});
}),
The output will be as follows:
Output Dropdown menu

How to filter a listview by DateTime

I am trying to create a sensor readings monitoring app and I need to get the records of the readings. I have written the records in list view by order of the time it was sent by the database. I need to be able to search the date and get all the readings that was received along that day.
This is where I get my data from:
http://mushroomdroid.online/dbscript-1.php
and this how I displayed the data using listview:
class RecordsPage extends StatefulWidget {
const RecordsPage({Key key}) : super(key: key);
#override
State<RecordsPage> createState() => _RecordsPageState();
}
class _RecordsPageState extends State<RecordsPage> {
final String url = "http://mushroomdroid.online/dbscript-1.php";
List<Readings> AllData = [];
final controller = TextEditingController();
#override
void initState() {
loadData();
}
loadData() async {
var response =
await http.get(Uri.parse(url), headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
String responseBody = response.body;
var jsonBody = json.decode(responseBody);
for (var data in jsonBody) {
AllData.add(new Readings(
int.parse(data['id']),
double.parse(data['temperature']),
double.parse(data['humidity']),
data['FanStatus'],
data['MistStatus'],
DateTime.parse(data['Time'])));
}
setState(() {});
AllData.forEach((someData) => print("FanStatus: ${someData.FanStatus}"));
} else {
print('Something went wrong');
}
}
#override
Widget build(BuildContext context) {
var container;
return ListView.builder(
itemCount: AllData.length,
itemBuilder: (_, index) {
return new Container(
child: new Card(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/records.jpg'),
fit: BoxFit.fill,
)),
padding: new EdgeInsets.all(12.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(
'READINGS ON: ${AllData[index].Time}',
style: TextStyle(fontSize: 10),
),
new Text(
'TEMPERATURE: ${AllData[index].temperature}',
style: TextStyle(fontSize: 20),
),
new Text(
'HUMIDITY: ${AllData[index].humidity}',
style: TextStyle(fontSize: 20),
),
new Text(
'FAN STATUS: ${AllData[index].FanStatus}',
style: TextStyle(fontSize: 15),
),
new Text(
'MIST STATUS: ${AllData[index].FanStatus}',
style: TextStyle(fontSize: 15),
),
],
),
),
),
);
});
}
}
Please help me. Thank you in advance!
In loadData() method for (var data in jsonBody), you can add some condition to check datetime valid before execute AllData.add.
Example: i write a filter extension that allow i get new list filtered by my condition (filter by name or time).
import 'package:intl/intl.dart';
final timeFm = DateFormat.yMd();
void main() {
var history = <LogHistory>[
LogHistory("A", DateTime(1990, 1, 1).millisecondsSinceEpoch),
LogHistory("A", DateTime(2020, 1, 1).millisecondsSinceEpoch),
LogHistory("B", DateTime(2020, 1, 1).millisecondsSinceEpoch),
];
print('originalObjects: $history');
print('---------------------------------------');
print('filtered by name: A');
print('result: ${history.filterBy(name: "A")}');
print('---------------------------------------');
print('filtered by time: 1/1/2000');
print('result: ${history.filterBy(time: DateTime(2000, 1, 1).millisecondsSinceEpoch)}');
print('---------------------------------------');
print('filtered by time: 1/1/2020');
print('result: ${history.filterBy(time: DateTime(2020, 1, 1).millisecondsSinceEpoch)}');
print('---------------------------------------');
print('filtered by both name & time: B + 1/1/2020');
print('result: ${history.filterBy(name: "B", time: DateTime(2020, 1, 1).millisecondsSinceEpoch)}');
}
class LogHistory {
String name;
int timeInMiliseconds;
LogHistory(this.name, this.timeInMiliseconds);
DateTime get time => DateTime.fromMillisecondsSinceEpoch(timeInMiliseconds);
#override
String toString() => "{name: $name, time: ${timeFm.format(time)}}";
}
extension LFilter on List<LogHistory> {
List<LogHistory> filterBy({String? name, int? time}){
final nameFilter = name ?? "";
final timeFilter = time != null ? DateTime.fromMillisecondsSinceEpoch(time) : null;
List<LogHistory> ret = [];
for (var object in this) {
var passFilter = true;
if(nameFilter.isNotEmpty && object.name != nameFilter){
passFilter = false;
}
if(timeFilter != null && object.time != timeFilter){
passFilter = false;
}
if(passFilter) ret.add(object);
}
return ret;
}
}
Result:
originalObjects: [{name: A, time: 1/1/1990}, {name: A, time: 1/1/2020}, {name: B, time: 1/1/2020}]
---------------------------------------
filtered by name: A
result: [{name: A, time: 1/1/1990}, {name: A, time: 1/1/2020}]
---------------------------------------
filtered by time: 1/1/2000
result: []
---------------------------------------
filtered by time: 1/1/2020
result: [{name: A, time: 1/1/2020}, {name: B, time: 1/1/2020}]
---------------------------------------
filtered by both name & time: B + 1/1/2020
result: [{name: B, time: 1/1/2020}]
Update: update example with your json
import 'package:intl/intl.dart';
final timeFm = DateFormat.yMd();
final json = [
{
"id": "1416",
"temperature": "32.65",
"humidity": "379.4",
"FanStatus": "ON",
"MistStatus": "OFF",
"Time": "2022-05-11 04:30:55"
},
{
"id": "1415",
"temperature": "32.47",
"humidity": "70.61",
"FanStatus": "ON",
"MistStatus": "ON \r\n",
"Time": "2022-05-11 04:20:54"
},
{
"id": "1352",
"temperature": "29.02",
"humidity": "77.61",
"FanStatus": "ON",
"MistStatus": "ON \r\n",
"Time": "2022-05-10 16:48:57"
},
{
"id": "1351",
"temperature": "28.99",
"humidity": "383.65",
"FanStatus": "OFF",
"MistStatus": "OFF",
"Time": "2022-05-10 16:38:57"
},
{
"id": "34",
"temperature": "33.71",
"humidity": "68.53",
"FanStatus": "ON",
"MistStatus": "ON",
"Time": "2021-06-01 03:31:47"
},
{
"id": "33",
"temperature": "33.7",
"humidity": "68.61",
"FanStatus": "ON",
"MistStatus": "ON",
"Time": "2021-05-09 03:31:47"
},
];
void main() {
var history = json.map(LogHistory.fromJson).toList();
print('total results from api: ${history.length}');
print('---------------------------------------');
print('filter by year: 2021');
print('found: ${history.filterByTime(year: 2021).length}');
print('---------------------------------------');
print('filter by month: 5');
print('found: ${history.filterByTime(month: 5).length}');
print('---------------------------------------');
print('filter by day: 10');
print('found: ${history.filterByTime(day: 10).length}');
print('---------------------------------------');
print('filter by both year and month: 2021-06');
print('found: ${history.filterByTime(year: 2021, month: 6).length}');
}
class LogHistory {
int id;
String timeRaw;
LogHistory.fromJson(Map<String, dynamic> data)
: id = int.parse(data['id']),
timeRaw = data['Time'];
DateTime get time => DateTime.parse(timeRaw);
#override
String toString() => "{id: $id, time: ${timeFm.format(time)}}";
}
extension LFilter on List<LogHistory> {
List<LogHistory> filterByTime({int? year, int? month, int? day}) {
List<LogHistory> ret = [];
for (var object in this) {
var passFilter = true;
if (year != null && object.time.year != year) {
passFilter = false;
}
if (month != null && object.time.month != month) {
passFilter = false;
}
if (day != null && object.time.day != day) {
passFilter = false;
}
if (passFilter) ret.add(object);
}
return ret;
}
}
Result:
total results from api: 6
---------------------------------------
filter by year: 2021
found: 2
---------------------------------------
filter by month: 5
found: 5
---------------------------------------
filter by day: 10
found: 2
---------------------------------------
filter by both year and month: 2021-06
found: 1

Flutter list query

Im trying to check a list inside list and then show it as ViewList
for example
const Sport = [
{
"Name": "James",
"SportTaq": ["Soccer", "American football"],
},
];
and then check list witch include loud Soccer
print(Sport.where((item) => item["SportTaq"].contains("Soccer")));
but it did not work can you help me with it please
You can do something like this:
void main() {
const Sport = [
{
"Name": "James",
"SportTaq": ["Soccer", "American football"],
},
{
"Name": "Bob",
"SportTaq": ["American football","basketball"],
},
];
print(Sport.where((item) {
List sports = item["SportTaq"];
return sports.contains("Soccer");
}).toList());
}

How json array pages by id dart

how all pages to map title print?
how json select example id=12 to map print title
{
"result": {
"name": "json1",
"pages": [
{
"zones": [
{
"title": "title1"
},
{
"title": "title2"
}
],
"id": 4
},
{
"zones": [
{
"title": "title3"
},
{
"title": "title4"
}
],
"id": 12
}
],
"creatorUserName": "admin",
"id": 2
}
}
List post = json;
children: post
.map( (post) => Container(
child: Center(child: Text(post.title]),)
))
.toList(),
I make a code to parse your json
var data = json.decode(jsonData);
var pagesArray = data["result"]["pages"];
pagesArray.forEach((page) {
var zones = page["zones"];
//Each id have your titles
int id = page["id"];
List<String> titles = new List();
zones.forEach((zone) {
titles.add(zone["title"]);
});
print("Id $id have this titles : ${titles.toString()}");
});

Flutter widget using generate to generate values

I have a flutter widget I am working on, and I want the options to be 0-99 by .25 increments. I'm pretty sure you use the generate function, but I can't figure out how to get it in the particular format I am using. What data type is it? etc. Can someone please take a look?
Widget _Display(display) {
if (display == true){
return Expanded(
child: ChoicesWidget(
Options: [
{
"display": "1", //these are the values I want to go from 0-99 by increments of .25.
"value": 1,
"checked": false
},
{
"display": "1.25",
"value": 1.25,
"checked": false
}
]
),);
}
else return Container();
}
Thanks!
Try a while loop and gen something for you:
Widget _Display(display) {
var min = 0.0;
var max = 99.0;
var current = min;
List<Map<String, Object>> options = [];
while (current <= max) {
options.add(
{
"display": current.toString(),
"value": current,
"checked": false,
},
);
current += 0.25;
}
if (display == true) {
return Expanded(
child: ChoicesWidget(Options: options),
);
} else {
return Container();
}
}