flutter: doesn't embed data from function to list - list

I want to create a list, those people location = "Barishal". That's why, I created a function and try to push data ( which data I obtained from getSpecific() function ) to a new list ( myList ). But It created a problem ....
here is my code-
class BookData extends ChangeNotifier {
List<MyModel> data = [
MyModel(name: "Abir", location: "Dhaka"),
MyModel(name: "Shuvro", location: "Barishal"),
MyModel(name: "Anik", location: "Barishal")
];
List<MyModel> get getMydata{
return data;
}
getSpecific (){
for(int i=0;i<data.length;i++){
if(data[i].location=="Barishal"){
print(data[i]);
return data[i];
}
}
}
List myList = getSpecific();
}
How can I fix this problem ?

You can copy paste run full code below
You can provide search string and use UnmodifiableListView<MyModel> and filter with _myData.where
code snippet
class BookData extends ChangeNotifier {
final List<MyModel> _myData = [
MyModel(name: "Abir", location: "Dhaka"),
MyModel(name: "Shuvro", location: "Barishal"),
MyModel(name: "Anik", location: "Barishal")
];
String _searchString = "";
UnmodifiableListView<MyModel> get books => _searchString.isEmpty
? UnmodifiableListView(_myData)
: UnmodifiableListView(
_myData.where((dog) => dog.location.contains(_searchString)));
void getSpecific(String searchString) {
_searchString = searchString;
print(_searchString);
notifyListeners();
}
}
working demo
full code
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:collection';
import 'package:provider/provider.dart';
class BookData extends ChangeNotifier {
final List<MyModel> _myData = [
MyModel(name: "Abir", location: "Dhaka"),
MyModel(name: "Shuvro", location: "Barishal"),
MyModel(name: "Anik", location: "Barishal")
];
String _searchString = "";
UnmodifiableListView<MyModel> get books => _searchString.isEmpty
? UnmodifiableListView(_myData)
: UnmodifiableListView(
_myData.where((dog) => dog.location.contains(_searchString)));
void getSpecific(String searchString) {
_searchString = searchString;
print(_searchString);
notifyListeners();
}
}
class MyModel {
final String name;
final String location;
MyModel({this.name, this.location});
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => BookData(),
child: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _controller = TextEditingController();
String _searchText;
#override
void initState() {
_controller.addListener(
() {
setState(() {
_searchText = _controller.text;
});
},
);
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Example',
home: Scaffold(
appBar: AppBar(
title: Text('Example'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TextField(
controller: _controller,
decoration: InputDecoration(
hintText: "Search",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(4.0),
),
),
),
onChanged: (value) {
Provider.of<BookData>(context, listen: false)
.getSpecific(value);
},
),
Consumer<BookData>(builder: (context, bookData, child) {
print(bookData.books.toString());
return Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: bookData.books.length,
itemBuilder: (context, index) => Card(
elevation: 3,
child: ListTile(
title: Text(bookData.books[index].name),
),
)),
);
}),
],
),
),
);
}
}

When you need to filter a list, you can use the where method.
Here's a simple example.
List<MyModel> myNewList = data.where((item) => item.location == "Barishal").toList();
Anyway, your code seems to be returning just the first item, not a list.

I fixed your code like below
List<MyModel> getSpecific (){
List<MyModel> result = [];
for(int i=0;i<data.length;i++){
if(data[i].location=="Barishal"){
print(data[i]);
result.add(data[i]);
}
}
return result;
}

Related

Passing data model as parameter through 2 pages

I have 2 pages in a flutter project. The first one is loginPage, which it's used for get user profile through Amplify DataStore query right after the login successful:
void _login() async{
final username = _usernameController.text.trim();
final password = _passwordController.text.trim();
ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Entrando no sistema...aguarde'), backgroundColor: Colors.green ) );
print('username: $username');
print('password: $password');
try{
_amplify.Auth.signOut();
var authResponse = await _amplify.Auth.signIn(username: username, password: password);
if (authResponse.isSignedIn){
List<Paciente> _listPacientes = await _amplify.DataStore.query(Paciente.classType, where: Paciente.EMAIL.eq(_usernameController.text.trim()));
Navigator.push(context, MaterialPageRoute(builder: (_) => MyHomePage(_listPacientes.elementAt(0))));
}
}
on AuthException catch (e){
print(e);
ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(e.message), backgroundColor: Colors.red ) );
}
}
And the HomePage whih I'd to show the results of the query executed in previous page (Login):
import 'package:flutter/material.dart';
import 'package:hmv/models/ModelProvider.dart';
import 'package:hmv/views/profile.dart';
class MyHomePage extends StatefulWidget {
Paciente paciente = new Paciente();
MyHomePage({Key? key, required Paciente paciente})
: super(key: key);
#override
State<StatefulWidget> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Paciente paciente = new Paciente();
void initState() async{
super.initState();
paciente = widget.paciente;
}
int _selectedIndex = 0;
List<Widget> _pages = <Widget>[
Text(
'Nome do paciente: ${paciente.nome_completo}'
),
Icon(
Icons.phone,
size: 150,
),
Icon(
Icons.camera,
size: 150,
),
Icon(
Icons.chat,
size: 150,
),
];
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
body: SafeArea(
child: Center(
child: _pages.elementAt(_selectedIndex)
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex, //New
onTap: _onItemTapped,
fixedColor: const Color(0xFF0065B3),
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "Home",
),
BottomNavigationBarItem(
icon: Icon(Icons.medical_services),
label: "Saúde",
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: "Perfil",
),
],
),
);
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
}
But when I try to use the page's parameters, I got the folowing error:
The instance member 'paciente' can't be accessed in an initializer.
Try replacing the reference to the instance member with a different expression
class MyHomePage extends StatefulWidget {
Paciente paciente = new Paciente();
MyHomePage({Key? key, required Paciente paciente})
: super(key: key);
replace it with
class MyHomePage extends StatefulWidget {
Paciente paciente;
MyHomePage({Key? key, required this.paciente})
: super(key: key);
also change your State:
class _MyHomePageState extends State<MyHomePage> {
// Remove these lines
// Paciente paciente = new Paciente();
// void initState() async{
// super.initState();
// paciente = widget.paciente;
// }
int _selectedIndex = 0;
List<Widget> _pages = <Widget>[
Text(
'Nome do paciente: ${widget.paciente.nome_completo}'
),

Flutter 'List<dynamic>' is not a subtype of type 'List<Widget>'

I receive this exception as thrown in the line ShowChart(data: dataapi.data) although i define it as a list below. I also tried to map my List data but no solution.
I am new to flutter, sorry if this is a dummy question.
The exception thrown :
════════ Exception caught by widgets library ═══════════════════════════════════
type 'List<Series<Hakedis, dynamic>>' is not a subtype of type 'List<Series<dynamic, num>>'
The relevant error-causing widget was
ShowChart
lib/screens/pageThree.dart:49
════════════════════════════════════════════════════════════════════════════════
The code:
// MAIN WIDGET
class PageThree extends StatefulWidget {
final String url;
const PageThree({this.url});
#override
_PageThreeState createState() => _PageThreeState();
}
class _PageThreeState extends State<PageThree> {
var chart;
Future<List<Hakedis>> getChartData(widget) async {
final jsonEndpoint = "https://securityconcern.php";
final response = await get(jsonEndpoint);
final List<dynamic> jsonData = jsonDecode(response.body);
return jsonData.map((data) => Hakedis.fromJson(data)).toList();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('GraphTest'),
),
body: Padding(
padding: EdgeInsets.all(8.0),
child: FutureBuilder<List>(
future: getChartData(widget),
builder: (context, dataapi) {
if (dataapi.hasError) print(dataapi.error);
return dataapi.hasData
? ShowChart(data: dataapi.data)
: Center(child: CircularProgressIndicator());
},
),
),
),
);
}
}
// CHART
class ShowChart extends StatelessWidget {
final List<Hakedis> data;
ShowChart({this.data});
static List<charts.Series<Hakedis, dynamic>> _createSampleData(dataAPI) {
return [
new charts.Series<Hakedis, dynamic>(
id: 'dis adet',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
areaColorFn: (_, __) =>
charts.MaterialPalette.blue.shadeDefault.lighter,
//x-axis
domainFn: (Hakedis hakedis, _) => hakedis.tarih,
//y-axis
measureFn: (Hakedis hakedis, _) => double.tryParse(hakedis.disadet).round(),
data: dataAPI,
)
];
}
#override
Widget build(BuildContext context) {
return Container(
child: charts.LineChart(
_createSampleData(data),
defaultRenderer:
new charts.LineRendererConfig(includeArea: true, stacked: true),
animate: true,
domainAxis: charts.NumericAxisSpec(
tickProviderSpec:
charts.BasicNumericTickProviderSpec(zeroBound: false),
),
),
);
}
}
/////////////////////////////////////
class Hakedis {
Hakedis({
this.id,
this.tarih,
this.disadet,
});
final int id;
String disadet;
DateTime tarih;
factory Hakedis.fromJson(Map<String, dynamic> jsonData) => Hakedis(
id: jsonData['id'],
tarih: jsonData['tarih'],
disadet: jsonData['disadet'],
);
Map<String, dynamic> toJson() => {
"id": id,
"tarih": tarih,
"disadet": disadet,
};
}
The data i am parsing via API;
(here is the "tarih" column gets month name as date, and i am trying to convert into datetime format)
[{"santiye1":"TSK_Ankara","tarih":"August","disadet":"1252"},{"santiye1":"TSK_Ankara","tarih":"September","disadet":"6528"},{"santiye1":"KMO_Istanbul","tarih":"August","disadet":"4382"},{"santiye1":"KMO_Istanbul","tarih":"September","disadet":"3317"},{"santiye1":"izmit","tarih":"January","disadet":"400"},{"santiye1":"izmit","tarih":"February","disadet":"7883"},{"santiye1":"izmit","tarih":"March","disadet":"9601"},{"santiye1":"izmit","tarih":"April","disadet":"25692"},{"santiye1":"izmit","tarih":"May","disadet":"15714"},{"santiye1":"izmit","tarih":"June","disadet":"28024"},{"santiye1":"izmit","tarih":"July","disadet":"18179"},{"santiye1":"izmit","tarih":"December","disadet":"3612"},{"santiye1":"Akkuyu1","tarih":"April","disadet":"10981"},{"santiye1":"Akkuyu1","tarih":"May","disadet":"4384"},{"santiye1":"Akkuyu1","tarih":"June","disadet":"8330"},{"santiye1":"Akkuyu1","tarih":"July","disadet":"5037"},{"santiye1":"Akkuyu1","tarih":"August","disadet":"6730"},{"santiye1":"Akkuyu1","tarih":"September","disadet":"3523"}]
From the data that you provided I have created a example
import 'package:dio_json_parsing/model.dart';
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PageThree(),
);
}
}
class PageThree extends StatefulWidget {
final String url;
const PageThree({this.url});
#override
_PageThreeState createState() => _PageThreeState();
}
class _PageThreeState extends State<PageThree> {
var chart;
Future<List<Hakedis>> getChartData(widget) async {
//final jsonEndpoint = "https://securityconcern.php";
//final response = await get(jsonEndpoint);
// Above where you fetch the data
final List<dynamic> data = dataFromJson(jsonString);
return data;
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('GraphTest'),
),
body: Padding(
padding: EdgeInsets.all(8.0),
child: FutureBuilder<List>(
future: getChartData(widget),
builder: (context, dataapi) {
if (dataapi.hasError) print(dataapi.error);
return dataapi.hasData
? ShowChart(data: dataapi.data)
: Center(child: CircularProgressIndicator());
},
),
),
),
);
}
}
class ShowChart extends StatelessWidget {
final List<Hakedis> data;
ShowChart({this.data});
List<charts.Series<dynamic, num>> _createSampleData(dataAPI) {
return [
new charts.Series<Hakedis, num>(
id: 'dis adet',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
areaColorFn: (_, __) =>
charts.MaterialPalette.blue.shadeDefault.lighter,
//x-axis
domainFn: (Hakedis hakedis, int number) {
return number;
},
//y-axis
measureFn: (Hakedis hakedis, _) =>
double.tryParse(hakedis.disadet).round(),
data: dataAPI,
)
];
}
#override
Widget build(BuildContext context) {
return Container(
child: charts.LineChart(
_createSampleData(data),
defaultRenderer:
new charts.LineRendererConfig(includeArea: true, stacked: true),
animate: true,
domainAxis: charts.NumericAxisSpec(
tickProviderSpec:
charts.BasicNumericTickProviderSpec(zeroBound: false),
),
),
);
}
}
String jsonString = '''[
{
"santiye1":"TSK_Ankara",
"tarih":"August",
"disadet":"1252"
},
{
"santiye1":"TSK_Ankara",
"tarih":"September",
"disadet":"6528"
},
{
"santiye1":"KMO_Istanbul",
"tarih":"August",
"disadet":"4382"
},
{
"santiye1":"KMO_Istanbul",
"tarih":"September",
"disadet":"3317"
},
{
"santiye1":"izmit",
"tarih":"January",
"disadet":"400"
},
{
"santiye1":"izmit",
"tarih":"February",
"disadet":"7883"
},
{
"santiye1":"izmit",
"tarih":"March",
"disadet":"9601"
},
{
"santiye1":"izmit",
"tarih":"April",
"disadet":"25692"
},
{
"santiye1":"izmit",
"tarih":"May",
"disadet":"15714"
},
{
"santiye1":"izmit",
"tarih":"June",
"disadet":"28024"
},
{
"santiye1":"izmit",
"tarih":"July",
"disadet":"18179"
},
{
"santiye1":"izmit",
"tarih":"December",
"disadet":"3612"
},
{
"santiye1":"Akkuyu1",
"tarih":"April",
"disadet":"10981"
},
{
"santiye1":"Akkuyu1",
"tarih":"May",
"disadet":"4384"
},
{
"santiye1":"Akkuyu1",
"tarih":"June",
"disadet":"8330"
},
{
"santiye1":"Akkuyu1",
"tarih":"July",
"disadet":"5037"
},
{
"santiye1":"Akkuyu1",
"tarih":"August",
"disadet":"6730"
},
{
"santiye1":"Akkuyu1",
"tarih":"September",
"disadet":"3523"
}
]''';
Model for the api :
// final data = dataFromJson(jsonString);
import 'dart:convert';
List<Hakedis> dataFromJson(String str) =>
List<Hakedis>.from(json.decode(str).map((x) => Hakedis.fromJson(x)));
String dataToJson(List<Hakedis> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Hakedis {
String santiye1;
String tarih;
String disadet;
Hakedis({this.santiye1, this.tarih, this.disadet});
Hakedis.fromJson(Map<String, dynamic> json) {
santiye1 = json['santiye1'];
tarih = json['tarih'];
disadet = json['disadet'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['santiye1'] = this.santiye1;
data['tarih'] = this.tarih;
data['disadet'] = this.disadet;
return data;
}
}
Check the example and let me know if it works

How can I use the shared_preferences package to save my string list?

I'm trying to save and read a list called "teams" as a shared_preference so every time I switch back to this screen and take a look at my teams list it isn't empty and shows the old values. No matter how I set it up it doesn't seem to work. Then I come back the list is empty. Do you guys have any ideas?
Here is my code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class TeamScreen extends StatefulWidget {
#override
_TeamScreenState createState() => _TeamScreenState();
}
class _TeamScreenState extends State<TeamScreen> {
List<String> teams = [];
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: teams.length,
itemBuilder: (context, index) {
return Team(
teams[index],
() => removeTeam(teams[index]),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () => newTeam(),
child: Icon(
CupertinoIcons.add,
),
),
);
}
void addTeam(String name) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
teams.add(name);
});
Navigator.of(context).pop();
prefs.setStringList('teams', teams);
}
void newTeam() {
showDialog<AlertDialog>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Name auswählen: '),
content: TextField(
onSubmitted: addTeam,
),
);
},
);
}
void removeTeam(String name) {
setState(() {
teams.remove(name);
});
}
}
class Team extends StatelessWidget {
final String name;
final Function remove;
const Team(this.name, this.remove);
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 22),
child: ListTile(
leading: Icon(Icons.sports_volleyball_outlined),
contentPadding: EdgeInsets.symmetric(vertical: 8.0),
title: Text(
name,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w600,
),
),
trailing: IconButton(
icon: Icon(CupertinoIcons.delete),
onPressed: () => remove(),
),
),
);
}
}
Your code seems almost perfect! just you didn't initialized your teams variable with the SharedPreferences in initState.
lets fix that :
Define a prefs variable
class _TeamScreenState extends State<TeamScreen> {
List<String> teams = [];
late SharedPreferences prefs; //Declare your prefs variable here but with late initializer.
...
Check if teams list is stored in local -> fetch it or if not -> create it with empty list.
void initState() {
super.initState();
tryListFetch(); // defined async function
}
void tryListFetch() async {
prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey('teams')) {
prefs.setStringList('teams', []); // created empty teams list on local storage
print('On device data is not available.');
return;
}
print('data avaialble');
teams = prefs.getStringList('teams') as List<String>;
}
Update your local data whenever you make changes in teams variable :
prefs.setStringList('teams', teams);
like in your removeTeam function :
void removeTeam(String name) {
setState(() {
teams.remove(name);
});
prefs.setStringList('teams', teams); //updated local storage's list
}
And in your addTeam function :
void addTeam(String name) async {
// SharedPreferences prefs = await SharedPreferences.getInstance(); //no need to initialize it here as we have already initialized it globally!
setState(() {
teams.add(name);
});
Navigator.of(context).pop();
prefs.setStringList('teams', teams);
}
Done !

flutter SingleChildScrollView remove item

I have the following code where I generate a list of items(data is taken from Firebase). I would like to implement a functionality to remove items but I don't know how to access the list and how to remove items:
class _MyOfferState extends State<MyOffer> {
List<Widget> items = [];
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
...
body: SingleChildScrollView(
child: Column(
children: [
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('Offers')
builder: (BuildContext context, snapshot) {
snapshot.data.docs.forEach((element) {
element.get('items').forEach((item) {
String _name = element['name'];
String _category = item['category'];
items.add(offer(name, category, context,...));
});
}
);
}
return new Column(
children: List.unmodifiable(() sync* {
yield* items;
}()),
);
},
),
}
}
This is a dynamic class where I have GestureDetector. The item should be deleted when a user clicks on the it.
dynamic offer(name, category, context,) {
return GestureDetector(
child: Container(
child: Row(
children: [
Text(name),
Text(category),
],
),
),
),
onTap: () {
// remove item should be here
},
);
}
Removing the offer from within itself is not the best practice but you can accomplish it in a number of ways. The first I can think of is to pass a function that removes it when creating the offer like this:
items.add(offer(name, category, context,..., () {
setState(() {
FirebaseFirestore.instance
.collection('Offers')
.doc(element['id'])
.delete();
items.remoev(index);
});
}));
You'll need to create the index beforehand and increase it each time but I don't recommend doing it.
The way I would done do this is change the offer to be:
dynamic offer(name, category, context,) {
return Container(
child: Row(
children: [
Text(name),
Text(category),
],
),
);
}
And when creating the offer wrap it in the GestureDetector like this:
items.add(GestureDetector(
child: offer(name, category, context,...)),
onTap: () {
setState(() {
FirebaseFirestore.instance
.collection('Offers')
.doc(element['id'])
.delete();
items.remoev(index);
});
},
);
You'll have to do the same thing with the index but I consider it a better approach since the child has no power over the parent and can't change its state which is a good practice.
you need to pass index of item and delete by index:
int index = 0;
snapshot.data.docs.forEach((element) {
element.get('items').forEach((item) {
String _name = element['name'];
String _category = item['category'];
items.add(offer(index, name, category, context,...));
index++;
});
Widget offer(int index, string name, string category, BuildContext context,) {
return GestureDetector(
child: Container(
child: Row(
children: [
Text(name),
Text(category),
],
),
),
),
onTap: () {
// remove item should be here
items.removeAt(index);
setState((){});
},
);
}
}
);
}
return new Column(
children: List.unmodifiable(() sync* {
yield* items;
}()),
);
Your list is getting build by Stream data the one you provided to your StreamBuilder, do create new list you need to change Stream value, I suggest to keep FirebaseFirestore.instance.collection('Offers') instance in a stream and modify the stream.
class _MyOfferState extends State<MyOffer> {
List<Widget> items = [];
StreamController _controller = StreamController();
#override
void initState() {
super.initState();
_controller.addStream( FirebaseFirestore.instance
.collection('Offers').snapshots());
}
// dont forgot to close stream
#override
void dispose() {
_controller.close();
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
...
body: SingleChildScrollView(
child: Column(
children: [
StreamBuilder<QuerySnapshot>(
stream: _controller.stream,
builder: (BuildContext context, snapshot) {
snapshot.data.docs.forEach((element) {
element.get('items').forEach((item) {
String _name = element['name'];
String _category = item['category'];
items.add(offer(name, category, context,(){
// remove function is here
snapshot.data.docs.removeWhere((e) => e.id == element.id);
_controller.add(snapshot.data);
});
});
}
);
}
return new Column(
children: List.unmodifiable(() sync* {
yield* items;
}()),
);
},
),
}
}
Also pass onTap to your widget function
dynamic offer(name, category, context, onTap) {
return GestureDetector(
child: Container(
child: Row(
children: [
Text(name),
Text(category),
],
),
),
),
onTap: onTap,
);
}

Pass a list for output in another view

In the 'Categories' class I have a list of elements. This list will be completed with more categories from Firebase. I want to read this list in another view (showCategories.dart) and thus output it in the other (showCategories.dart) view.
How can I pass the list to another view and access the elements of the list in this other view?
Code for categories.dart
class Categories with ChangeNotifier {
List<Category> _cats = [
Category(
id: 'c1',
titel: 'Kategorie #1',
bezeichnung: 'Erste Kategorie',
gruppe: '1',
),
Category(
id: 'c2',
titel: 'Kategorie #2',
bezeichnung: 'Zweite Kategorie',
gruppe: '2',
),
Category(
id: 'c3',
titel: 'Kategorie #3',
bezeichnung: 'Dritte Kategorie',
gruppe: '3',
),
];
List<Category> get cats {
return [..._cats];
}
get length => null;
Category findById(String id) {
return _cats.firstWhere(
(prod) => prod.id == id
);
}
Future<void> fetchAndSetCategories() async {
const url = 'https://....firebaseio.com/categories.json';
//print(_cats);
try {
final response = await http.get(url);
final extractedData = json.decode(response.body) as Map<String, dynamic>;
final List<Category> loadedCategories = [];
extractedData.forEach((catId, catData) {
loadedCategories.add(Category(
id: catId,
titel: catData['titel'],
bezeichnung: catData['bezeichnung'],
gruppe: catData['gruppe'],
));
});
_cats = loadedCategories;
notifyListeners();
} catch(error) {
throw error;
}
}
}
Code for viewCategories.dart
class ViewCategories extends StatefulWidget {
#override
_ViewCategoriesState createState() => _ViewCategoriesState();
}
class _ViewCategoriesState extends State<ViewCategories> {
#override
void initState() {
Provider.of<Categories>(context, listen: false).fetchAndSetCategories();
super.initState();
}
}
You can copy paste run full code below
You can directly use Consumer to access data of your model
code snippet
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Categories(),
child: MyApp(),
),
);
}
...
return Scaffold(
body: Consumer<Categories>(builder: (context, categoryData, child) {
print(categoryData.cats.toString());
return ListView.builder(
shrinkWrap: true,
itemCount: categoryData.cats.length,
itemBuilder: (context, index) => Card(
elevation: 3,
child: ListTile(
title: Text(categoryData.cats[index].titel),
),
));
}),
);
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
import 'dart:convert';
class ViewCategories extends StatefulWidget {
#override
_ViewCategoriesState createState() => _ViewCategoriesState();
}
class _ViewCategoriesState extends State<ViewCategories> {
#override
void initState() {
//Provider.of<Categories>(context, listen: false).fetchAndSetCategories();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Consumer<Categories>(builder: (context, categoryData, child) {
print(categoryData.cats.toString());
return ListView.builder(
shrinkWrap: true,
itemCount: categoryData.cats.length,
itemBuilder: (context, index) => Card(
elevation: 3,
child: ListTile(
title: Text(categoryData.cats[index].titel),
),
));
}),
);
}
}
class Category {
String id;
String titel;
String bezeichnung;
String gruppe;
Category({this.id, this.titel, this.bezeichnung, this.gruppe});
}
class Categories with ChangeNotifier {
List<Category> _cats = [
Category(
id: 'c1',
titel: 'Kategorie #1',
bezeichnung: 'Erste Kategorie',
gruppe: '1',
),
Category(
id: 'c2',
titel: 'Kategorie #2',
bezeichnung: 'Zweite Kategorie',
gruppe: '2',
),
Category(
id: 'c3',
titel: 'Kategorie #3',
bezeichnung: 'Dritte Kategorie',
gruppe: '3',
),
];
List<Category> get cats {
return [..._cats];
}
get length => null;
Category findById(String id) {
return _cats.firstWhere((prod) => prod.id == id);
}
Future<void> fetchAndSetCategories() async {
const url = 'https://....firebaseio.com/categories.json';
//print(_cats);
try {
/*final response = await http.get(url);
final extractedData = json.decode(response.body) as Map<String, dynamic>;
final List<Category> loadedCategories = [];
extractedData.forEach((catId, catData) {
loadedCategories.add(Category(
id: catId,
titel: catData['titel'],
bezeichnung: catData['bezeichnung'],
gruppe: catData['gruppe'],
));
});*/
final List<Category> loadedCategories = [];
loadedCategories.add(Category(
id: "c9",
titel: 'c9 titel',
bezeichnung: 'c9 bezeichnung',
gruppe: 'c9 gruppe',
));
loadedCategories.add(Category(
id: "c19",
titel: 'c19 titel',
bezeichnung: 'c19 bezeichnung',
gruppe: 'c19 gruppe',
));
_cats = loadedCategories;
notifyListeners();
} catch (error) {
throw error;
}
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Categories(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Consumer<Categories>(builder: (context, categoryData, child) {
print(categoryData.cats.toString());
return Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: categoryData.cats.length,
itemBuilder: (context, index) => Card(
elevation: 3,
child: ListTile(
title: Text(categoryData.cats[index].titel),
),
)),
);
}),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Categories>(context, listen: false).fetchAndSetCategories();
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ViewCategories()),
);
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
));
}
}