Save list getting from JSON URL in firestore collection - list

My small app, is getting list of users from JSON link then store it in the List, I wanna this list into usersCollection collection ref of firestore
my code
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:yat_flutter_app/main.dart';
import 'usersList.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
CollectionReference usersCollection =
FirebaseFirestore.instance.collection('users');
Future<List<User>> getUsers() async {
var data = await http
.get("https://www.json-generator.com/api/json/get/bYKKPeXRcO?indent=2");
var jasonData = json.decode(data.body);
List<User> users = [];
for (var i in jasonData) {
User user = User(i["index"], i["about"], i["name"], i["picture"],
i["company"], i["email"]);
users.add(user);
}
return users;
}
#override
Widget build(BuildContext context) {
List<User> usersList = getUsers() as List<User>;
return Container(
child: Column(
children: [
FutureBuilder(
future: getUsers(),
builder: (BuildContext context, AsyncSnapshot asyncSnapshop) {
if (asyncSnapshop.hasData) {
return Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: asyncSnapshop.data.length,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 5,
color: Colors.cyan[50],
child: ListTile(
trailing: Icon(Icons.share),
title: Text(asyncSnapshop.data[index].name, style: TextStyle(fontFamily: 'Tahoma',fontSize: 20,fontWeight: FontWeight.bold),),
leading: CircleAvatar(
backgroundImage: NetworkImage(
asyncSnapshop.data[index].picture +
asyncSnapshop.data[index].index.toString() +
".jpg"),
),
subtitle: Text(asyncSnapshop.data[index].email,style: TextStyle(fontFamily: 'Tahmoma',fontSize: 18),),
onTap: (){
Navigator.push(context, new MaterialPageRoute(builder: (context)=>
detailsPage(asyncSnapshop.data[index])
));
},
onLongPress: ()=>
Fluttertoast.showToast(
msg: asyncSnapshop.data[index].name,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.green[900],
textColor: Colors.white,
fontSize: 16.0
),
),
);
}),
);
} else {
return Text("Loading, please wait...");
}
},
),
ElevatedButton(
child: Text('Save data'),
onPressed: () => {
usersCollection.add(getUsers()); // here's I am trying to add the result of getUsers into usersCollection
}),
],
),
);
}
}

To push an object to Firestore you need to convert your object to map.
You can just add this function to your class:
Map<String, dynamic> toMap() {
return {
'field1': value1,
'field2': value1,
};
}
To push a List , you need to convert all objects to map, you can do it with following method:
static List<Map> ConvertToMap({List myList }) {
List<Map> steps = [];
myList.forEach((var value) {
Map step = value.toMap();
steps.add(step);
});
return steps;
}
Or simply , see how to convert List to Map
I hope it will be useful

To push this list to Firestore you need to fromJson and toJson methods in your model class
factory User.fromJson(Map<String, dynamic> data){
return User(
index: data['index'] as int,
about: data['about'] as String,
name: data['name'] as String,
picture: data['picture'] as String,
company: data['company'] as String,
email: data['email'] as String );
}
Map<String, dynamic> toJson(){
return {
"index": index,
"about" : about,
"name" : name,
"picture" : picture,
"company" : company,
"email" : email,
};
}
instead that I would like to suggest using json_serializable library
then you need to do some changes in your future method like this
getUsers().then((users) {
// add users to map
});
and then you can use fromJson method to push it to firestore database

Firebase realtime database and firestore are no SQL databases where data will be stored in Parent child relation or Tree structure.
For you to store list of data you can convert your list into Map
Map can be initialised as follows
Map<String, String> toMap() {
return {
'Fruit': "Mango",
'Flower': "Lotus",
'Vegetable': "Potato",
};
}
After you have Map you can set value to the firestore. You can use the below code to set value
Map<String, Object> city = new Map<>();
//Loop through your list and load Map (City) values
db.collection("cities").document("LA").set(city)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully written!");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error writing document", e);
}
});
You can convert List of items to map using this
Java: How to convert List to Map

Related

Not able to convert DataModel Future List to a list item

I tried to add data from populateSearch() method into the allData List in Custom search, but it doesn't accept the data.
please help me to add the data from populateSearch() into the least in the Customsearch class during the initialization so that it would be used as suggestion list during search.
I tried to search over the internet and it has been now two days without solution.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:zhebsa_assistant/model/dzongkha_zhebsa.dart';
import '../../database/za_darabase.dart';
import 'search_result.dart';
class CustomSearch extends SearchDelegate {
//bb
final DatabaseService _databaseService = DatabaseService();
late List<String> searchData;
List<SearchDataModel> items = [];
List<SearchDataModel> suggestion = [];
// ListViewNoteState i = ListViewNoteState();
Future<List<SearchDataModel>> _getSearch() async {
return await _databaseService.populateSearch();
}
// final allData = [];
List<String> allData = [
'Abc',
'Def',
'བཀའ་སློབ།',
'ཁྲག',
'སྐུ་ཁྲག',
'བཀབ་ནེ།',
];
final recentData = [
'བཀབ་ནེ།',
'བཀའ་སློབ།',
'ཁྲག',
'སྐུ་ཁྲག',
];
CustomSearch({
String hintText = "འཚོལ།/Search",
}) : super(
searchFieldLabel: hintText,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.search,
);
#override
ThemeData appBarTheme(BuildContext context) {
final ThemeData theme = Theme.of(context);
// final InputDecorationTheme? searchFieldDecorationTheme;
return theme.copyWith(
dividerTheme: const DividerThemeData(
color: Colors.white,
),
// primaryIconTheme: const IconThemeData(color: Colors.white),
scaffoldBackgroundColor: Colors.white, // for the body color
// brightness: Brightness.dark,
inputDecorationTheme: searchFieldDecorationTheme ??
const InputDecorationTheme(
// focusedBorder: UnderlineInputBorder(
// borderSide: BorderSide(color: Colors.white),
// ),
border: InputBorder.none,
hintStyle: TextStyle(
color: Colors.white,
),
),
textSelectionTheme: const TextSelectionThemeData(
cursorColor: Colors.white,
), // cursor color
textTheme: Theme.of(context).textTheme.copyWith(
headline6: const TextStyle(
color: Colors.white,
// fontSize: 20.0,
decorationThickness: 0.0000001,
),
),
);
}
#override
List<Widget>? buildActions(BuildContext context) {
return [
IconButton(
onPressed: () {
if (query.isEmpty) {
close(context, null);
} else {
query = '';
showSuggestions(context);
}
// stopPronunciation();
SearchResults(searchQuery: "").stopPronunciation();
},
icon: const Icon(Icons.clear),
)
];
}
#override
Widget? buildLeading(BuildContext context) {
return IconButton(
onPressed: () {
close(context, null);
// stopPronunciation();
SearchResults(searchQuery: "").stopPronunciation();
},
// icon: const Icon(Icons.arrow_back),
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
);
}
#override
Widget buildResults(BuildContext context) {
return SearchResults(searchQuery: query);
}
#override
Widget buildSuggestions(BuildContext context) {
final suggestionList = query.isEmpty
? recentData
: allData.where((p) {
final dataLower = p.toLowerCase();
final queryLower = query.toLowerCase();
return dataLower.startsWith(queryLower);
}).toList();
return buildSuggestionsSuccess(suggestionList);
}
Widget buildSuggestionsSuccess(List<String> suggestionList) =>
ListView.builder(
itemCount: suggestionList.length,
itemBuilder: (context, index) {
final suggestion = suggestionList[index];
final queryText = suggestion.substring(0, query.length);
final remainingText = suggestion.substring(query.length);
return ListTile(
onTap: () {
query = suggestion;
showResults(context);
},
leading: const Icon(
Icons.dangerous,
),
title: RichText(
text: TextSpan(
text: queryText,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
children: [
TextSpan(
text: remainingText,
style: const TextStyle(color: Colors.black45),
),
]),
),
// title: Text(suggestionList[index]),
);
},
);
}
//SearchList Model
class SearchDataModel {
final String sWord;
SearchDataModel({required this.sWord});
Map<String, dynamic> toMap() {
return {
'sWord': sWord,
};
}
factory SearchDataModel.fromMap(Map<String, dynamic> map) {
return SearchDataModel(
sWord: map['sWord'],
);
}
String toJson() => json.encode(toMap());
factory SearchDataModel.fromJson(String source) =>
SearchDataModel.fromMap(json.decode(source));
}
import 'dart:convert';
import '../model/dzongkha.dart';
import '../model/zhebsa.dart';
import '../model/dzongkha_zhebsa.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseService {
static final DatabaseService _databaseService = DatabaseService._internal();
factory DatabaseService() => _databaseService;
DatabaseService._internal();
static Database? _database;
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}
Future<Database> _initDatabase() async {
final databasePath = await getDatabasesPath();
final path = join(databasePath, 'zhebsa_assistant0.db');
return await openDatabase(
path,
onCreate: _onCreate,
version: 1,
onConfigure: (db) async => await db.execute('PRAGMA foreign_keys = ON'),
);
}
Future<void> _onCreate(Database db, int version) async {
await db.execute(
'''CREATE TABLE Dzongkha(
dId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
dWord TEXT NOT NULL UNIQUE,
dPhrase TEXT,
dHistory TEXT,
dFavourite TEXT,
dUpdateTime TEXT)''',
);
await db.execute(
'''CREATE TABLE Zhebsa(
zId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
zWord TEXT NOT NULL UNIQUE,
zPhrase TEXT,
zPronunciation TEXT,
zHistory TEXT,
zFavourite TEXT,
zUpdateTime TEXT)''',
);
// Run the CREATE {dzongkha_zhebsa} TABLE statement on the database.
await db.execute(
'CREATE TABLE DzongkhaZhebsa(DzongkhadId INTEGER NOT NULL, ZhebsazId INTEGER NOT NULL, updateTime TEXT, PRIMARY KEY (DzongkhadId, ZhebsazId), FOREIGN KEY(DzongkhadId) REFERENCES Dzongkha(dId) ON DELETE SET NULL, FOREIGN KEY(ZhebsazId) REFERENCES Zhebsa(zId) ON DELETE SET NULL)',
);
//Insert raw data to database
var dt = DateTime.now();
var dtStr = dt.toIso8601String();
await db.rawInsert(
'INSERT INTO Dzongkha(dId, dWord, dPhrase, dUpdateTime) VALUES(1, "བཀབ་ནེ།", "བཀབ་ནེ་བཀབ་གོ།", "$dtStr"),(2, "ཁ།", "ཁ། inn", "$dtStr"), (3, "བརྩེ་བ།", "བརྩེ་བ། kindness", "$dtStr")');
await db.rawInsert(
'INSERT INTO Zhebsa(zId, zWord, zPhrase, zPronunciation, zUpdateTime) VALUES(1, "སྐུ་གཟན།", "སྐུ་གཟན yes", "2.mp3", "$dtStr"), (2, "ན༌བཟའ།", "ན༌བཟའ་ཨིན།", "2.mp3", "$dtStr"), (3, "ཞལ།", "ཞལ། is correct", "3.mp3", "$dtStr"), (4, "བརྩེ་བ།", "བརྩེ་བ། honoriffic", "4.mp3", "$dtStr")');
await db.rawInsert(
'INSERT INTO DzongkhaZhebsa (DzongkhadId, ZhebsazId, updateTime) VALUES(1, 1, "$dtStr"), (1, 2, "$dtStr"), (2, 3, "$dtStr"), (3, 4, "$dtStr")');
}
Future<List<SearchDataModel>> populateSearch() async {
final db = await _databaseService.database;
final searchData = await db.rawQuery(
'(SELECT dWord FROM Dzongkha) UNION (SELECT zWord FROM Zhebsa)');
// return searchData.map((e) => SearchDataModel.fromMap(e)).toList();
return List.generate(searchData.length,
(index) => SearchDataModel.fromMap(searchData[index]));
}
}
First, edit your SearchDataModel class like this:
class SearchDataModel {
final String sWord;
SearchDataModel({required this.sWord});
factory SearchDataModel.fromMap(Map<String, Object?> map) =>
SearchDataModel(sWord: map['sWord']);
Map<String, Object?> toMap() => {'sWord': sWord};
}
Then, in your populateSearch() method, try this:
Future<List<SearchDataModel>> populateSearch() async {
final db = await _databaseService.database;
final searchData = await db.rawQuery(
'(SELECT dWord FROM Dzongkha) UNION (SELECT zWord FROM Zhebsa)');
return searchData.map(SearchDataModel.fromMap).toList();
}

How can I get more than one Doc in a Collection of a List of Strings? (Flutter)

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,
};
}

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 !

How can I check value in dropdown for register form

I have a registration form in my application and I want to check if the DropDown value is empty or not. So I will give a warning to the screen. But I couldn't use DropDown value on checkFieldStatus function. How can I get this?
These are my codes that i used for my app:
class Register extends StatefulWidget {
#override
_RegisterState createState() => _RegisterState();
}
class _RegisterState extends State<Register> {
List listGender = ["Erkek", "Kız"];
List listTeacher = ["Oğulcan Baybars", "Kübra Yeşilkazak"];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String genderHolder;
String teacherHolder;
var _imageFile = null;
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: [
CustomDropDownField(
list: listGender,
hintText: "Cinsiyet",
value: genderHolder,
),
CustomDropDownField(
list: listTeacher,
hintText: "Öğretmeniniz",
value: teacherHolder,
),
ElevatedButton(
onPressed: () {
checkFieldStatus();
},
child: Text("Kayıt Ol")),
],
),
),
);
}
Future<void> checkFieldStatus() async {
if (_imageFile != null) {
showDialog(
context: context,
builder: (context) {
return ErrorAlertDialog(
message: "Resim yüklendi",
);
});
} else {
**Where I want to do the checks**
? registerUser()
: displayDialog("Lütfen formdaki bütün alanları doldurun.";
}
}
}
My CustomDropDownField like this:
import 'package:flutter/material.dart';
class CustomDropDownField extends StatefulWidget {
final List list;
final String hintText;
String value;
CustomDropDownField({
Key key,
this.list,
this.hintText,
this.value,
}) : super(key: key);
#override
_CustomDropDownFieldState createState() => _CustomDropDownFieldState();
}
class _CustomDropDownFieldState extends State<CustomDropDownField> {
#override
Widget build(BuildContext context) {
return Container(
child: DropdownButton(
isExpanded: true,
hint: Text(widget.hintText),
items: widget.list.map((valueItem) {
return DropdownMenuItem(value: valueItem, child: Text(valueItem));
}).toList(),
value: widget.value,
onChanged: (newValue) {
setState(() {
widget.value = newValue;
});}),);}
CustomDropDownField only changes the String value in its own state it does not reflect to the _RegisterState screen you can do a few different things:
Pass a callback function that updates the value in the _RegisterState screen
or even better
Use a state management like Provider or Bloc to update the value.

Cache two Lists in flutter

I want to cache two lists that got from Firebase to use to later when the user is offline
This is the full code for my list display screen -
import 'package:flutter/material.dart';
import 'package:naamaa/calculations/name-list-calc.dart';
List namesList = List();
List meaningsList = List();
class NameList extends StatefulWidget {
#override
_NameListState createState() => _NameListState();
}
class _NameListState extends State<NameList> {
Future<String> getPosts() async {
var names = await NameListCalc().nameListCalc();
namesList.addAll(names[0]);
meaningsList.addAll(names[1]);
String s = 'test';
return s;
}
#override
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: getPosts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Scaffold(
resizeToAvoidBottomPadding: false,
body: ListView.builder(
padding: EdgeInsets.zero,
itemBuilder: (context, position) {
return Row(
children: <Widget>[
Container(
width: 100,
child: Text(namesList[position]),
),
Container(
child: Text(meaningsList[position]),
)
],
);
},
itemCount: namesList.length,
),
);
} else {
return Text(':(');
}
},
);
}
}
I want to cache namesList and meaningsList for later use.
If someone can help it would be great :)
I didn't get complete requirement by your question description but you can use shared_preferences library to store the data list as following
Add following line pubspec.yaml
dependencies:
flutter:
sdk: flutter
shared_preferences:
You can use this example and add more utility methods as per you requirement.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() async {
AppConfig.init(() {
runApp(MyApp());
});
}
class CustomModel {
int id;
String name;
CustomModel({this.id, this.name});
factory CustomModel.fromJson(Map<String, dynamic> json) {
return CustomModel(id: json["id"], name: json["name"]);
}
Map<String, dynamic> toJson() => {"id": id, "name": name};
#override
String toString() {
return "id: $id, name: $name";
}
}
class AppConfig {
static Future init(VoidCallback callback) async {
WidgetsFlutterBinding.ensureInitialized();
await SharedPreferenceUtils.init();
callback();
}
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class SharedPreferenceUtils {
static SharedPreferences prefs;
static init() async {
prefs = await SharedPreferences.getInstance();
// storing lists
await putStringList("m_list", ["abc", "def"]);
await putObjectList("data",
[CustomModel(id: 1, name: "Bob"), CustomModel(id: 2, name: "Alice")]);
}
static Future<bool> putStringList(String key, List<String> list) async {
return prefs.setStringList(key, list);
}
static List<String> getStringList(String key) {
return prefs.getStringList(key);
}
static Future<bool> putObjectList(String key, List<Object> list) async {
if (prefs == null) return null;
List<String> _dataList = list?.map((value) {
return json.encode(value);
})?.toList();
return prefs.setStringList(key, _dataList);
}
static List<T> getObjList<T>(String key, T f(Map v),
{List<T> defValue = const []}) {
if (prefs == null) return null;
List<Map> dataList = getObjectList(key);
List<T> list = dataList?.map((value) {
return f(value);
})?.toList();
return list ?? defValue;
}
static List<Map> getObjectList(String key) {
if (prefs == null) return null;
List<String> dataList = prefs.getStringList(key);
return dataList?.map((value) {
Map _dataMap = json.decode(value);
return _dataMap;
})?.toList();
}
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(SharedPreferenceUtils.getStringList("m_list").toString()),
Text(SharedPreferenceUtils.getObjList<CustomModel>(
"data", (v) => CustomModel.fromJson(v)).toString()),
],
),
),
),
);
}
}
You don't need to store the lists in init() as it's done for this example. You can also pass data from one widget to others in multiple ways and if you are looking for state management then you can use BLOC or providers.