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,
));
}
}
Related
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}'
),
I am using AWS Cognito and Flutter framework to build an app.
The cognito suddenly is not working when I changed the layout(?) of the app, please help me out!
When I first built the app I made it so the login page would come up first but now I changed the page layout so the users can login after looking around the app.
Thisis what I get in the console when I hit the login button:
W/CognitoUserSession(22147): CognitoUserSession is not valid because idToken is null.
D/AWSMobileClient(22147): Sending password.
D/AWSMobileClient(22147): Using USER_SRP_AUTH for flow type.
E/UserContextDataProvider(22147): Exception in creating JSON from context data
E/amplify:flutter:auth_cognito(22147): AuthException
I/flutter (22147): Could not login - Sign in failed
this is how my Widget build in main looked like before:
Widget build(BuildContext context) {
return MaterialApp(
title: 'Photo Gallery App',
theme: ThemeData(visualDensity: VisualDensity.adaptivePlatformDensity),
home: StreamBuilder<AuthState>(
stream: _authService.authStateController.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Navigator(
pages: [
if (snapshot.data!.authFlowStatus == AuthFlowStatus.login)
MaterialPage(
child: LoginPage(
didProvideCredentials: _authService.loginWithCredentials,
shouldShowSignUp: _authService.showSignUp
)
),
if (snapshot.data!.authFlowStatus == AuthFlowStatus.signUp)
MaterialPage(
child: SignUpPage(
didProvideCredentials: _authService.signUpWithCredentials,
shouldShowLogin: _authService.showLogin
)
),
if (snapshot.data!.authFlowStatus == AuthFlowStatus.verification)
MaterialPage(
child: VerificationPage(
didProvideVerificationCode: _authService.verifyCode
)
),
if (snapshot.data!.authFlowStatus == AuthFlowStatus.session)
MaterialPage(
child: CameraFlow(shouldLogOut: _authService.logOut)
)
],
onPopPage: (route, result) => route.didPop(result),
);
} else {
return Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
);
}
}
)
);}
Now, it looks like this:
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'App',
theme: ThemeData(visualDensity: VisualDensity.adaptivePlatformDensity),
home: StreamBuilder<AuthState>(
stream: AuthService.authStateController.stream, // PREVIOUS: _authService.authStateController.stream
builder: (context, snapshot) {
if (snapshot.hasData) {
return Navigator(
pages: [
if (snapshot.data!.authFlowStatus == AuthFlowStatus.none || snapshot.data!.authFlowStatus == AuthFlowStatus.session)
MaterialPage(
child: TabBarFlow(
authFlowStatus: snapshot.data!.authFlowStatus,
shouldShowSignUp: _authService.showSignUp,
shouldShowLogin: _authService.showLogin,
)
),
if (snapshot.data!.authFlowStatus == AuthFlowStatus.login)
MaterialPage(
child: LoginPage(
didProvideCredentials: _authService.loginWithCredentials,
shouldShowSignUp: _authService.showSignUp,
shouldShowNone: _authService.showNone,
)
),
if (snapshot.data!.authFlowStatus == AuthFlowStatus.signUp)
MaterialPage(
child: SignUpPage(
didProvideCredentials: _authService.signUpWithCredentials,
shouldShowLogin: _authService.showLogin,
shouldShowNone: _authService.showNone,
)
),
if (snapshot.data!.authFlowStatus == AuthFlowStatus.verification)
MaterialPage(
child: VerificationPage(
didProvideVerificationCode: _authService.verifyCode
)
)
],
onPopPage: (route, result) => route.didPop(result),
);
} else {
return Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
);
}
}
),
);}
I think the problem might be coming from TabbarFlow which looks like this:
#override
void initState() {
super.initState();
_widgetOptions = <Widget>[
HomePage(),
SearchAvatarPage(),
SelectAvatarPage(),
MyPage(),
SettingsPage(
authFlowStatus: widget.authFlowStatus,
shouldShowSignUp: widget.shouldShowSignUp,
shouldShowLogin: widget.shouldShowLogin
)
];
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.black,
unselectedItemColor: Colors.grey,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: ''
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: ''
),
BottomNavigationBarItem(
icon: ClipOval(
child: Container(
width: 35,
height: 35,
color:Color.fromRGBO(37, 67, 117, 1),
child: Icon(Icons.add, color: Colors.white)
)
),
label: ''
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: ''
),
BottomNavigationBarItem(
icon: Icon(Icons.menu_outlined),
label: ''
)
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
);}
Amplify logic
import 'dart:async';
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_flutter/amplify.dart';
import 'auth_credentials.dart';
enum AuthFlowStatus { none, login, signUp, verification, session }
class AuthState {
final AuthFlowStatus authFlowStatus;
AuthState({required this.authFlowStatus});
}
class AuthService {
static final authStateController = StreamController<AuthState>();
late AuthCredentials _credentials;
void showNone() {
final state = AuthState(authFlowStatus: AuthFlowStatus.none);
authStateController.add(state);
}
void showSignUp() {
final state = AuthState(authFlowStatus: AuthFlowStatus.signUp);
authStateController.add(state);
}
void showLogin() {
final state = AuthState(authFlowStatus: AuthFlowStatus.login);
authStateController.add(state);
}
void loginWithCredentials(AuthCredentials credentials) async {
try {
final result = await Amplify.Auth.signIn(
username: credentials.username, password: credentials.password
);
if (result.isSignedIn) {
final state = AuthState(authFlowStatus: AuthFlowStatus.session);
authStateController.add(state);
} else {
print('User could not be signed in');
}
} on AuthException catch (authError) {
print('Could not login - ${authError.message}');
}
}
void signUpWithCredentials(SignUpCredentials credentials) async {
try {
final userAttributes = {'email': credentials.email};
final result = await Amplify.Auth.signUp(
username: credentials.username,
password: credentials.password,
options: CognitoSignUpOptions(userAttributes: userAttributes)
);
if (result.isSignUpComplete) {
loginWithCredentials(credentials);
} else {
this._credentials = credentials;
final state = AuthState(authFlowStatus: AuthFlowStatus.verification);
authStateController.add(state);
}
} on AuthException catch (authError) {
print('Failed to sign up - ${authError.message}');
}
}
void verifyCode(String verificationCode) async {
try {
final result = await Amplify.Auth.confirmSignUp(
username: _credentials.username, confirmationCode: verificationCode
);
if (result.isSignUpComplete) {
loginWithCredentials(_credentials);
} else {
// Add later
}
} on AuthException catch (authError) {
print('Could not verify code - ${authError.message}');
}
}
void checkAuthStatus() async {
try {
await Amplify.Auth.fetchAuthSession();
final state = AuthState(authFlowStatus: AuthFlowStatus.session);
authStateController.add(state);
} catch (_) {
final state = AuthState(authFlowStatus: AuthFlowStatus.none);
authStateController.add(state);
}
}
static void logOut() async {
try {
await Amplify.Auth.signOut();
final state = AuthState(authFlowStatus: AuthFlowStatus.none);
authStateController.add(state);
} on AuthException catch (authError) {
print('Could not log out - ${authError.message}');
}
}
}
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
My question is if I can put a List in a Doc from Firebase.
Here is my Code:
Future getPosts() async {
var test = await FirebaseFirestore.instance
.collection("Profiles")
.doc(auth.currentUser.displayName)
.collection("Following")
.doc()
.get()
.asStream()
.toList();
print(test);
qn = await FirebaseFirestore.instance
.collection("Posts")
.doc() // here I want the string of All documents from the List
.collection("_Posts")
.get();
}
The Code is pretty shitty but yeah hope you can Help.
Here is a working code implementing both FutureBuilder() and StreamBuilder():
class PlayGround extends StatefulWidget {
const PlayGround({Key? key}) : super(key: key);
#override
_PlayGroundState createState() => _PlayGroundState();
}
class _PlayGroundState extends State<PlayGround> {
FirebaseFirestore _db = FirebaseFirestore.instance;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
//using a Future ( Fetch once )
Expanded(
child: FutureBuilder<List<PostsModel>>(
future: fetchUserPosts('someUID'),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return LinearProgressIndicator();
}
return ListView.builder(itemBuilder: (context, index) {
return Container(
child: Text(snapshot.data![index].title.toString()));
});
},
)),
//using a stream (Real Time)
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: _db
.collection('Users')
.doc('someUID')
.collection('Posts')
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return LinearProgressIndicator();
}
List<PostsModel> _postsStream = snapshot.data!.docs
.map((e) =>
PostsModel.fromMap(e.data() as Map<String, dynamic>))
.toList();
return ListView.builder(itemBuilder: (context, index) {
return Container(
child: Text(_postsStream[index].title.toString()));
});
},
)),
],
),
);
}
//to get list of posts from Firestore
Future<List<PostsModel>> fetchUserPosts(userID) async {
var result = await _db
.collection('Users')
.doc(userID)
.collection('Posts')
// .orderBy("SomeThing")
.get();
List<PostsModel> postsModel =
result.docs.map((doc) => PostsModel.fromMap(doc.data())).toList();
return postsModel;
}
}
class PostsModel {
final String? title;
final num? likes;
PostsModel({
this.title,
this.likes,
});
factory PostsModel.fromMap(Map<String, dynamic> json) => PostsModel(
title: json["title"],
likes: json["likes"],
);
Map<String, dynamic> toMap() => {
"title": title,
"likes": likes,
};
}
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;
}