How can we use JSON with datatable? - json

I am new on flutter but I work a lot for learning all I need for my projects.
I have a JSON sent by a server using HTTP:
[{"equipe1":"PSG","equipe2":"DIJON","type_prono":"1N2"},{"equipe1":"MONACO","equipe2":"REIMS","type_prono":"1N2"},{"equipe1":"TOULOUSE","equipe2":"RENNES","type_prono":"1N2"},{"equipe1":"MONTPELLIER","equipe2":"STRASBOURG","type_prono":"1N2"},{"equipe1":"AMIENS","equipe2":"METZ","type_prono":"1N2"},{"equipe1":"BREST","equipe2":"ANGERS","type_prono":"1N2"},{"equipe1":"LORIENT","equipe2":"CHAMBLY","type_prono":"1N2"}]
And I try to set it to a datatable widget but it seems complicated to do.
Now here is my entire code :
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:async';
// Create a Form widget.
class Affiche_grille extends StatefulWidget {
#override
Affiche_grille_State createState() {
return Affiche_grille_State();
}
}
// Create a corresponding State class.
// This class holds data related to the form.
class Affiche_grille_State extends State<Affiche_grille> {
#override
final _formKey = GlobalKey<FormState>();
Grille_display() async {
// SERVER LOGIN API URL
var url = 'http://www.axis-medias.fr/game_app/display_grid.php';
// Store all data with Param Name.
var data = {'id_grille': 1};
// Starting Web API Call.
var response = await http.post(url, body: json.encode(data));
// Getting Server response into variable.
var match = json.decode(response.body);
}
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
var listmatch = Grille_display();
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
DataTable(
columnSpacing: 20,
columns: [
DataColumn(
label: Text("Eq 1"),
numeric: false,
tooltip: "",
),
DataColumn(
label: Text("Eq 2"),
numeric: false,
tooltip: "",
),
DataColumn(
label: Text("Type pro"),
numeric: false,
tooltip: "",
),
],
rows: EquipeList.map((equipe_detail) => DataRow(
cells: [
DataCell(
Text(equipe_detail['equipe1'].toString()),
),
DataCell(
Text(equipe_detail['equipe2'].toString()),
),
DataCell(
Text(equipe_detail['type_prono'].toString()),
),
]),
).toList(),
)
],
)
);
}
}
class Match_detail {
String equipe1;
String equipe2;
String typeProno;
Match_detail({this.equipe1, this.equipe2, this.typeProno});
Match_detail.fromJson(Map<String, dynamic> json) {
equipe1 = json['equipe1'];
equipe2 = json['equipe2'];
typeProno = json['type_prono'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['equipe1'] = this.equipe1;
data['equipe2'] = this.equipe2;
data['type_prono'] = this.typeProno;
return data;
}
}
class EquipeList {
List<Match_detail> breeds;
EquipeList({this.breeds});
factory EquipeList.fromJson(List<dynamic> json) {
return EquipeList(
breeds: json
.map((e) => Match_detail.fromJson(e as Map<String, dynamic>))
.toList());
}
}
It doesn't work :( it says me : error: The method 'map' isn't defined for the class 'EquipeList'. (undefined_method at [flutter_app] lib

You can copy paste run full code below
You can use package https://pub.dev/packages/json_table
working demo
full code
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:json_table/json_table.dart';
class SimpleTable extends StatefulWidget {
#override
_SimpleTableState createState() => _SimpleTableState();
}
class _SimpleTableState extends State<SimpleTable> {
final String jsonSample =
'[{"equipe1":"PSG","equipe2":"DIJON","type_prono":"1N2"},{"equipe1":"MONACO","equipe2":"REIMS","type_prono":"1N2"},{"equipe1":"TOULOUSE","equipe2":"RENNES","type_prono":"1N2"},{"equipe1":"MONTPELLIER","equipe2":"STRASBOURG","type_prono":"1N2"},{"equipe1":"AMIENS","equipe2":"METZ","type_prono":"1N2"},{"equipe1":"BREST","equipe2":"ANGERS","type_prono":"1N2"},{"equipe1":"LORIENT","equipe2":"CHAMBLY","type_prono":"1N2"}]';
bool toggle = true;
#override
Widget build(BuildContext context) {
var json = jsonDecode(jsonSample);
return Scaffold(
body: Container(
padding: EdgeInsets.all(16.0),
child: toggle
? Column(
children: [
JsonTable(
json,
showColumnToggle: true,
tableHeaderBuilder: (String header) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: 8.0, vertical: 4.0),
decoration: BoxDecoration(
border: Border.all(width: 0.5),
color: Colors.grey[300]),
child: Text(
header,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.display1.copyWith(
fontWeight: FontWeight.w700,
fontSize: 14.0,
color: Colors.black87),
),
);
},
tableCellBuilder: (value) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: 4.0, vertical: 2.0),
decoration: BoxDecoration(
border: Border.all(
width: 0.5,
color: Colors.grey.withOpacity(0.5))),
child: Text(
value,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.display1.copyWith(
fontSize: 14.0, color: Colors.grey[900]),
),
);
},
allowRowHighlight: true,
rowHighlightColor: Colors.yellow[500].withOpacity(0.7),
paginationRowCount: 20,
),
SizedBox(
height: 20.0,
),
Text("Simple table which creates table direclty from json")
],
)
: Center(
child: Text(getPrettyJSONString(jsonSample)),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.grid_on),
onPressed: () {
setState(
() {
toggle = !toggle;
},
);
}),
);
}
String getPrettyJSONString(jsonObject) {
JsonEncoder encoder = new JsonEncoder.withIndent(' ');
String jsonString = encoder.convert(json.decode(jsonObject));
return jsonString;
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SimpleTable(),
);
}
}

I think you should first, convert this json into a real dart class so it can be easier to work with. You could create a class in dart/flutter called "Equipe" and run a map on the json. The [] means that you're dealing with a list of data.
But if you don't want to create a class, you could definitely work with with the json response, mapping over the list. I'm going to try to cook it up for you quickly. NB: Just remember to convert the json too, if it hasn't been done yet.
DataTable(
columnSpacing: 20,
columns: [
DataColumn(
label: Text("Eq 1"),
numeric: false,
tooltip: "",
),
DataColumn(
label: Text("Eq 2"),
numeric: false,
tooltip: "",
),
DataColumn(
label: Text("Type pro"),
numeric: false,
tooltip: "",
),
],
rows: equipeDetails.map((equipeDetail) => DataRow(
cells: [
DataCell(
Text(equipeDetail['equipe1'].toString()),
),
DataCell(
Text(equipeDetail['equipe2'].toString()),
),
DataCell(
Text(equipeDetail['type_prono'].toString()),
),
]),
).toList(),
)

I have done it:
Grille_display() async {
// SERVER LOGIN API URL
var url = 'http://www.axis-medias.fr/game_app/display_grid.php';
// Store all data with Param Name.
var data = {'id_grille': 1};
// Starting Web API Call.
var response = await http.post(url, body: json.encode(data));
// Getting Server response into variable.
var match = json.decode(response.body);
}
I think I need to create 2 class, instead of using equipeDetails and equipeDetail.
I need to display only equipe1 and equipe2 in table and use type prono for display radio button 1N2 or 12.

To populate data Table with json, create 2 methods .
One for populating the column headings.
Second one for populating the rows.
then pass the methods as value to datatable.
DataTable(
columnSpacing: 20,
columns:
dataTableColumnHeaderSetter(
dashBoardItems!
.oSsummary),
rows: dashBoardItems!.oSsummary
.mapIndexed(
(index, details) => DataRow(
cells:
dataTableColumnValueSetter(
dashBoardItems!
.oSsummary),
),
)
.toList()),
Method one.
List<DataColumn> dataTableColumnHeaderSetter(List<OSsummary> summary) {
return List.generate(summary.length, (i) {
return DataColumn(
label: Text(
summary[i].head,
textAlign: TextAlign.center,
),
numeric: true,
tooltip: "",
);
});
}
Method Two.
List<DataCell> dataTableColumnValueSetter(List<OSsummary> summary) {
return List.generate(summary.length, (i) {
return DataCell(
Text(
summary[i].value,
textAlign: TextAlign.center,
),
showEditIcon: false,
placeholder: false,
);
});
}
Do wrap the datatable in future builder and use snapshot.data for accessing the json data.

Related

flutter addAll isn't defined for Iterable

I need your help for the following problem on line 22.
Flutter says, that "addAll isn't defined for Iterable". What do I need to change in my code or do you need additional Information?
import 'package:flutter/material.dart';
import 'package:MyApp/jsonApi/dataModels/dataModelPlaces.dart';
import 'package:MyApp/jsonApi/parsers/repositoryPlaces.dart';
class ShareAppScreen extends StatefulWidget {
#override
_ShareAppScreenState createState() => _ShareAppScreenState();
}
class _ShareAppScreenState extends State<ShareAppScreen> {
//List<DataModelPlaces> _places = <DataModelPlaces>[];
Iterable<DataModelPlaces> _places = <DataModelPlaces>[];
Iterable<DataModelPlaces> _placesDisplay = <DataModelPlaces>[];
bool _isPlacesLoading = false;
#override
void initState() {
super.initState();
fetchPlaces().then((pvalue) {
setState(() {
_isPlacesLoading = false;
_places.addAll(pvalue); //<- here I have a problem that addAll isn't defined for Iterable
_placesDisplay = _places;
print('User display pin Records: ${pvalue.data!.length}');
var i=0;
while (i < pvalue.data!.length){
print('User display Lat of $i: ${pvalue.data![i].attributes!.latitude}');
print('User display Long of $i: ${pvalue.data![i].attributes!.latitude}');
i++;
}
});
});
}
List stocksList = [
CompanyStocks(name: "Intel Corp", price: 56.96),
CompanyStocks(name: "HP Inc", price: 32.43),
CompanyStocks(name: "Apple Inc", price: 133.98),
CompanyStocks(name: "Microsoft Corporation", price: 265.51)
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Users List ${_places.length}'),
),
body: SafeArea(
child: Container(
child: ListView.builder(
itemCount: stocksList.length,
itemBuilder: (context, index) {
return Card(
child: Padding(
padding: EdgeInsets.all(10),
child: ListTile(
title: Text(
stocksList[index].name,
style: TextStyle(
fontSize: 20,
),
),
leading: CircleAvatar(
child: Text(
stocksList[index].name[0],
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
),
),
trailing: Text("\$ ${stocksList[index].price}"),
),
),
);
},
),
),
),
);
}
}
class CompanyStocks {
String name;
double price;
CompanyStocks({required this.name,required this.price});
}
At the End I would need an Variable "_places" and "_placesDisplay" of DataModelPlaces which I can use in in Place of the List "stocksList" which is working but not _places / _placesDisplay"
Many Thanks
Roman
Iterable does not have .addAll. You need to convert it to a List first so you can addAll the elements to it such as:
Update: My bad. toList() will return a new list! You should try the alternative approach below
// This wrong since it will return a new list (wrong)
// _places.toList().addAll(pvalue)
Alternatively, you can change the definition to be List instead of Iterable:
from:
Iterable<DataModelPlaces> _places = <DataModelPlaces>[];
Iterable<DataModelPlaces> _placesDisplay = <DataModelPlaces>[];
To:
List<DataModelPlaces> _places = <DataModelPlaces>[];
List<DataModelPlaces> _placesDisplay = <DataModelPlaces>[];
Update:
As discussed in the comments, you want to make sure that fetchPlaces is returning an Iterable in order to use _places.addAll(pvalue) otherwise, if it's a single object, use _places.add(pvaule).

How to generate a List to the second screen in flutter from a JSON?

I am trying to create a list from the value inside a JSON. I can get the length but not for the data. My main goal is to create a list of items based on their popularity.
child: Row(
children: [
...List.generate(
"items"[0].length,
(index) {
if (["items"][index].isPopular) { // here I want to generate a list for the value isPopular
return BreakfastCard(breakfast: ('items'[0] as Map<String, dynamic>[index]); // Here I want to call the function from other screen
}
And when I tried to change the code to this
"items"[0].length,
(index) {
if (["items"][index][isPopular]) { // the error here is *Conditions must have a static type of 'bool'.*
return BreakfastCard(breakfast: ['items'][0][index]); // the error here is *The argument type 'String' can't be assigned to the parameter type 'Breakfast'.*
The JSON data is like this
{
"items":[{
"id": 1,
"rating": "0.0",
"images": [
"assets/images/cilantro.png"
],
"title": "Cilantro and Kale Pesto Toast with a Fried Egg",
"time": 15,
"description": "Sliced bread is the perfect blank canvas, ready to be loaded up with virtuous ingredients.",
" rating": "4.8",
"isFavorite": false,
"isPopular": true,
}]
}
Here is my code for the card. In this part, there were no error and it show what I want.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:fema/models/Breakfast.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../constants.dart';
import '../size_config.dart';
class BreakfastCard extends StatefulWidget {
BreakfastCard({
Key? key,
this.width = 140,
this.aspectRetio = 1.02,
required this.breakfast,
}) : super(key: key);
final double width, aspectRetio;
Breakfast breakfast;
#override
_BreakfastCardState createState() => _BreakfastCardState();
}
class _BreakfastCardState extends State<BreakfastCard> {
#override
Widget build(BuildContext context) {
Future<String> _loadloadBreakfastAsset() async {
return await rootBundle.loadString('assets/breakfast.json');
}
Future<BreakfastCard> loadBreakfast() async {
String jsonAddress = await _loadloadBreakfastAsset();
final jsonResponse = json.decode(jsonAddress);
// This now updates the breakfast property in the main class.
widget.breakfast = Breakfast.fromJson(jsonResponse);
// This return value is thrown away, but this line is necessary to
// resolve the Future call that FutureBuilder is waiting on.
return Future<BreakfastCard>.value();
}
SizeConfig().init(context);
return FutureBuilder(
future: loadBreakfast(),
builder: (BuildContext, AsyncSnapshot<dynamic>snapshot){
return Padding(
padding: EdgeInsets.only(left: getProportionateScreenWidth(20)),
child: SizedBox(
width: getProportionateScreenWidth(140),
child: GestureDetector(
onTap: (){},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: 1.02,
child: Container(
padding: EdgeInsets.all(getProportionateScreenWidth(20)),
decoration: BoxDecoration(
color: kSecondaryColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(15),
),
child: Hero(
tag: widget.breakfast.id.toString(),
child: Image.asset(widget.breakfast.images[0]),
),
),
),
const SizedBox(height: 10),
Text(
widget.breakfast.title,
style: const TextStyle(color: Colors.black),
maxLines: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${widget.breakfast.calories} cal |",
style: TextStyle(
fontSize: getProportionateScreenWidth(18),
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
Text(
"${widget.breakfast.time} min",
style: TextStyle(
fontSize: getProportionateScreenWidth(18),
fontWeight: FontWeight.w600,
color: kPrimaryColor,
),
),
InkWell(
borderRadius: BorderRadius.circular(50),
onTap: () { widget.breakfast.isFavorite = !widget.breakfast.isFavorite;},
child: Container(
padding: EdgeInsets.all(getProportionateScreenWidth(8)),
height: getProportionateScreenWidth(28),
width: getProportionateScreenWidth(28),
child: SvgPicture.asset(
"assets/icons/Heart Icon_2.svg",
color: widget.breakfast.isFavorite
? const Color(0xFFFF4848)
: const Color(0xFFDBDEE4),
),
),
),
],
)
],
),
),
),
);
}
);
}
}
And my problem is in here. Where the list will be generated. I am new to flutter and I have difficulties to solve the problem. In here I can correctly create a function to fetch the data from the BreakfastCard.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:fema/components/breakfast_card.dart';
import 'package:fema/models/Breakfast.dart';
import 'package:flutter/services.dart';
import '../../../size_config.dart';
import 'section_title.dart';
class Breakfast extends StatelessWidget {
const Breakfast({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
Future<String> _loadloadBreakfastAsset() async {
return await rootBundle.loadString('assets/breakfast.json');
}
Future<Breakfast> loadBreakfast() async {
String jsonAddress = await _loadloadBreakfastAsset();
Map<String,dynamic> map = json.decode(jsonAddress);
List<dynamic> items = map["items"];
// This return value is thrown away, but this line is necessary to
// resolve the Future call that FutureBuilder is waiting on.
return Future<Breakfast>.value();
}
return FutureBuilder(
future: loadBreakfast(),
builder: (BuildContext, AsyncSnapshot<dynamic>snapshot){
return Column(
children: [
Padding(
padding:
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)),
child: SectionTitle(title: "BREAKFAST", press: () {}),
),
SizedBox(height: getProportionateScreenWidth(20)),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
...List.generate(
items[0].length,
(index) {
if (items[index].isPopular) {
return BreakfastCard(breakfast: );
}
return const SizedBox
.shrink(); // here by default width and height is 0
},
),
SizedBox(width: getProportionateScreenWidth(20)),
],
),
)
],
);
});
}
}
You need to put "items" into a Map first. You are trying to use the String object "items" to populate your list. You want the data from the json to populate it.
Get the data into a usable object first.
Map<String, dynamic> map = jsonDecode(data);
List<dynamic> items = map["items"];
Then you can populate your list from that data.
child: Row(
children: [
...List.generate(
items.length,
(index) {
if (items[index].isPopular) {
return BreakfastCard(breakfast: (items[0]));
}
Your errors are from trying to use json data improperly as the conditional for an if statement.
The other error is because you are trying to send a String as an argument for a Breakfast object when it needs something else (I don't know what that is. You didn't post what a BreakfastCard class looks like at the time I wrote this.)
Dart and Flutter documentation is very good. Try this out https://flutter.dev/docs/development/data-and-backend/json

How to put the result of a function into a Text widget in Flutter?

I am new in this language and I am working on a BMI(body mass index) app. As you see in the picture below:
I take the user input and calculate the result, and print out the result in console. For example:
I/flutter ( 4500): 2.25
I/flutter ( 4500): 20.0 // this is the result of BMI
I/flutter ( 4500): you are at your ideal weight. // this is the explanation
I want to show these results in a Text widget to let user see them. But I do not know how to do it. How can I take the value of the result from a function and add it to interface?
Here is my code, and in code I pointed out where did I stuck. Main function:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'calculation.dart';
void main() => runApp(MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'BMI';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title),
centerTitle: true,
backgroundColor: Colors.amber[900],
),
body: Center(
child: MyStatefulWidget(),
),
),
);
}
}
enum SingingCharacter { lafayette, jefferson }
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
SingingCharacter _character = SingingCharacter.lafayette;
double height=1;
double weight=1;
String info1="";
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10.0),
child:Scrollbar(
child:SingleChildScrollView(
child:Card(
color: Colors.amber[50],
child:Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0, 30, 10, 10),
child: Text("Sex:",
style:TextStyle(fontSize: 24, letterSpacing: 1.0)),
),
ListTile(
title: const Text('Female',
style:TextStyle(fontSize: 18, letterSpacing: 1.0)
),
leading: Radio(
activeColor: Colors.orange,
value: SingingCharacter.lafayette,
groupValue: _character,
onChanged: (SingingCharacter value) {
setState(() {
_character = value;
});
},
),
),
ListTile(
title: const Text('Male',
style:TextStyle(fontSize: 18, letterSpacing: 1.0,)
),
leading: Radio(
activeColor: Colors.orange,
value: SingingCharacter.jefferson,
groupValue: _character,
onChanged: (SingingCharacter value) {
setState(() {
_character = value;
});
},
),
),
SizedBox(height: 10.0),
Text("Your height:",
style:TextStyle(fontSize: 24, letterSpacing: 1.0)
),
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.fromLTRB(30, 0, 50, 10),
child: TextField(
decoration: new InputDecoration(labelText: "Your height(cm)"),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
], // Only numbers can be entered
onSubmitted: (input1){
if(double.parse(input1)>0){
setState(() => height=double.parse(input1));
print(input1);
}
},
),
),
SizedBox(height: 20),
Text("Your weight:",
style:TextStyle(fontSize: 24, letterSpacing: 1.0)
),
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.fromLTRB(30, 0, 50, 10),
child: new TextField(
decoration: new InputDecoration(labelText: "Your weight(kg)"),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
], // Only numbers can be entered
onSubmitted: (input2){
if (double.parse(input2)>0){
// print(weight);
setState(() {
return weight=double.parse(input2);
});
}
},
),),
SizedBox(height: 10,),
RaisedButton(
padding:EdgeInsets.fromLTRB(20, 5, 20, 5),
onPressed: () async{
await Calculation(height, weight);
// return Calculation.info1 ??? //i don't know how to take info1 from calculation function
},
color: Colors.amber[900],
child:Text(
'Calculate',
style:TextStyle(
color: Colors.white,
fontSize: 30,
letterSpacing: 2.0,
),
),
),
SizedBox(height: 20,),
Text('Results: $height,$weight'),
// Text('Calculation.info1'), // i do not know how to show info in a text box.
],
),
),
),
),
);
}
}
Calculation function;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:math';
void Calculation(height,weight) {
double squarevalue = pow(height, 2);
double newsquare = squarevalue / 10000;
String info1="";
print(newsquare);
double value = weight / newsquare;
print(value);
// return value.toString();
if (value < 18.5) {
print("your weight is less than your ideal weight.");
// setState(() => info1="your weight is less than your ideal weight."); //i do not know how to set
// info1 to a new text
// return info1;
}
if (value > 25) {
if (value > 30) {
print("your weight is more than your ideal weight, your health is under risk.");
// info1="your weight is more than your ideal weight, your health is under risk.";
}
else {
print("your weight is more than your ideal weight.");
// info1="your weight is more than your ideal weight.";
}
}
else {
print("you are at your ideal weight.");
// info1="you are at your ideal weight.";
}
}
Instead of returning void from Calculation(height,weight) function, return String and display the string value in the Text Widget.
String Calculation(height,weight) {
....// your code with all conditions
return "you are at your ideal weight."
}
In onpressed function, update the obtained string to the state variable inside setState.
onPressed: () async{
String info = await Calculation(height, weight);
setState(){
infoDisplayedInText = info;
}
},

Flutter how to save list data locally

I am building a to-do list app and I would like to store the data locally such that every time I open the app, I get all the tasks that I had created previously. I am new to flutter and this is my first app. I already tried saving the data to a file, creating a JSON file to save the data and tried using a database. Nothing seems to work. Can someone help me with this?
This is my code: -
import 'package:flutter/material.dart';
class toDoList extends StatefulWidget
{
bool data = false;
#override
createState()
{
return new toDoListState();
}
}
class toDoListState extends State<toDoList>
{
List<String> tasks = [];
List<bool> completedTasks = [];
List<String> descriptions = [];
List<bool> importance = [];
#override
Widget build(BuildContext context)
{
return new Scaffold
(
body: buildToDoList(),
floatingActionButton: new FloatingActionButton
(
onPressed: addToDoItemScreen,
tooltip: 'Add Task',
child: new Icon(Icons.add),
),
);
}
Widget buildToDoList()
{
return new ListView.builder
(
itemBuilder: (context, index)
{
if(index < tasks.length)
{
if(tasks[index] == "#45jiodg{}}{OHU&IEB")
{
tasks.removeAt(index);
descriptions.removeAt(index);
importance.removeAt(index);
}
return row(tasks[index], descriptions[index], index);
};
},
);
}
Widget row(String task, String description, int index)
{
return Dismissible(
key: UniqueKey(),
background: Container(color: Colors.red, child: Align(alignment: Alignment.center, child: Text('DELETE', textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontSize: 18),))),
direction: DismissDirection.horizontal,
onDismissed: (direction) {
setState(() {
tasks.removeAt(index);
if(completedTasks[index])
{
completedTasks.removeAt(index);
}
descriptions.removeAt(index);
importance.removeAt(index);
});
Scaffold.of(context).showSnackBar(SnackBar(content: Text(task+" dismissed")));
},
child: CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
title: Text(task, style: (completedTasks[index]) ? TextStyle(decoration: TextDecoration.lineThrough) : TextStyle(),),
subtitle: Text(descriptions[index], style: (completedTasks[index]) ? TextStyle(decoration: TextDecoration.lineThrough) : TextStyle(),),
isThreeLine: true,
secondary: (importance[index])? Icon(Icons.error, color: Colors.red,) : Text(''),
value: completedTasks[index],
onChanged: (bool value) {
setState(() {
if(completedTasks[index])
{
completedTasks[index] = false;
}
else
{
completedTasks[index] = true;
}
});
},
));
}
void addToDoItemScreen() {
int index = tasks.length;
while (importance.length > tasks.length) {
importance.removeLast();
}
importance.add(false);
tasks.add("#45jiodg{}}{OHU&IEB");
descriptions.add("No Description");
completedTasks.add(false);
Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
return StatefulBuilder(builder: (context, setState) { // this is new
return new Scaffold(
appBar: new AppBar(title: new Text('Add a new task')),
body: Form(
child: Column(
children: <Widget>[
TextField(
autofocus: true,
onSubmitted: (name) {
addToDoItem(name);
//Navigator.pop(context); // Close the add todo screen
},
decoration: new InputDecoration(
hintText: 'Enter something to do...',
contentPadding: const EdgeInsets.all(20.0),
border: OutlineInputBorder()),
),
TextField(
//autofocus: true,
//enabled: descriptions.length > desc,
onSubmitted: (val) {
addDescription(val, index);
},
decoration: new InputDecoration(
hintText: 'Enter a task decription...',
contentPadding: const EdgeInsets.all(20.0),
border: OutlineInputBorder()),
),
Row(
children: <Widget> [
Switch(
value: importance[index],
onChanged: (val) {
setState(() {
});
impTask(index);
},
),
Text('Important Task', style: TextStyle(fontSize: 18)),
],
),
RaisedButton(onPressed: () { Navigator.pop(context); }, child: Text('DONE', style: TextStyle(fontSize: 20)),)
],
),
));
});
}));
}
void addToDoItem(String task)
{
setState(() {
tasks.last = task;
});
}
void addDescription(String desc, int index)
{
setState(() {
descriptions.last = desc;
});
}
void impTask(int index)
{
setState(() {
if(importance[index])
{
importance[index] = false;
}
else
{
importance[index] = true;
}
});
}
}
I have 4 lists with the data. I need a simple way to save the lists such that the next time I open the app, the lists retain the data that was saved in them, the last time I had closed the app.
To do this you'll certainly have to use the path_provider package with this tutorial on the flutter.dev website. You should then be able to register a file and read it at the start of your application.
Once you have imported the path_provider and the dart:io packages, you can do something like this :
final directory = await getApplicationDocumentsDirectory();
final File file = File('${directory.path}/jsonObjects.json');
if (await file.exists()) {
json = await file.readAsString();
} else {
file.writeAsString(json);
}
First you get the application document directory ( the path ), then you create a File with the right path. Then if the file already exist, you read it, else you create it with the json you got and you should be good to go !

How do I load my local json into List<Map> variable?

How do I load my local json into List< Map > variable?
This my local json.
[
{“id”: 00”, “name”: ”TRL”},
{“id”: 01”, “name”: ”USD”},
{“id”: 02”, “name”: ”GBP”},
{“id”: 03”, “name”: ”EUR”},
]
However this works:
List<Map> _myCurrency = [
{“id”: 00”, “name”: ”TRL”},
{“id”: 01”, “name”: ”USD”},
{“id”: 02”, “name”: ”GBP”},
{“id”: 03”, “name”: ”EUR”},
];
My problem is I move my currency data into currency.json file. I can load the json but I cannot assign to List< Map > variable. Any help please?
UPDATE:
String jsonTCBanks =
await rootBundle.loadString("packages/capi/currency.json");
List<Map> _myCurrency = json.decode(jsonTCBanks);
I get error as;
type 'List<dynamic>' is not a subtype of type 'List<Map<dynamic, dynamic>>'
If I use Map _myCurrency the json.decode works, but I loose the key, value properties.
UPDATE-2:
I am keep getting error as:
I/flutter (16273): The following assertion was thrown building MyHomePage(dirty, state: _MyHomePageState#44865):
I/flutter (16273): type 'MappedListIterable<Map<dynamic, dynamic>, DropdownMenuItem<dynamic>>' is not a subtype of type
I/flutter (16273): 'List<DropdownMenuItem<String>>'
class _MyHomePageState extends State<MyHomePage> {
String _mySelectedCurrency;
List<Map> _myCurrencies;
#override
void initState() {
// TODO: implement initState
super.initState();
_loadLocalJsonData();
}
Future _loadLocalJsonData() async {
String jsonCurrency = await rootBundle
.loadString("packages/capi/currency.json");
setState(() {
_myCurrencies = List<Map>.from(jsonDecode(jsonCurrency) as List);
print("*******_myCurrencies: $_myCurrencies");// This part works correctly
});
}
#override
Widget build(BuildContext context) {
return _myCurrencies == null ? _buildWait(context) : _buildRun(context);
}
// TODO: BUILD RUN
Widget _buildRun(BuildContext context) {
final _itemsName = _myCurrencies.map((c) {
return new DropdownMenuItem<String>(
value: c["id"].toString(),
child: new Text(c["name"].toString()),
);
}).toList();
return new Scaffold(
key: _scaffoldKey,
body: new SafeArea(
top: false,
bottom: false,
child: new Form(
key: _formKey,
child: new ListView(
padding: const EdgeInsets.symmetric(
horizontal: 16.0, vertical: 32.0),
children: <Widget>[
//TODO: CURRENCY ###########################################
new FormField<String>(
builder: (FormFieldState<String> state) {
return InputDecorator(
decoration: InputDecoration(
labelText: 'CHOOSE CURRENCY',
labelStyle: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
color: Colors.green.shade700),
errorText: state.hasError ? state.errorText : null,
),
isEmpty: _mySelectedCurrency == '',
child: new DropdownButtonHideUnderline(
child: new DropdownButton<String>(
style: TextStyle(
fontSize: 14.0,
color: Colors.black,
fontWeight: FontWeight.w500,
),
value: _mySelectedCurrency,
isDense: true,
onChanged: (String newValue) {
setState(() {
_mySelectedCurrency = newValue;
state.didChange(newValue);
});
},
items: _itemsName,
),
),
);
},
validator: (val) {
return val != '' ? null : 'Choose Currency...';
},
),
],
))));
}
// TODO: BUILD WAIT
Widget _buildWait(BuildContext context) {
return new Scaffold(
body: new Center(child: CircularProgressIndicator()),
);
}
}
You need to decode it from a string to a data structure and adjust the type by creating a new list with the desired type where you pass the list returned from jsonDecode:
import 'dart:convert';
...
List<Map> _myCurrency = List<Map>.from(jsonDecode(json) as List);
final currencyItems = _myCurrency.map(
(c) => DropdownMenuItem<String>(c['id'], child: Text(c['name'])).toList();
DropdownButton(items: currencyItems);