Flutter SharedPreferences how to load all saved? - flutter

How can I load all saved in SharedPreferences?
I have saved lots of bools and need to load all to a list!
This is how I save:
SharedPreferences sharedPreferences;
bool isfavorit;
#override
void initState() {
super.initState();
SharedPreferences.getInstance().then((SharedPreferences sp) {
sharedPreferences = sp;
isfavorit = sharedPreferences.getBool('${widget.id}');
// will be null if never previously saved
if (isfavorit == null) {
isfavorit = false;
persist(isfavorit); // set an initial value
}
setState(() {});
});
}
void persist(bool value) {
setState(() {
isfavorit = value;
});
sharedPreferences?.setBool('${widget.id}', value);
}

List<bool> prefList = [];
var sharedPreferences = await SharedPreferences.getInstance();
Set<String> keys = sharedPreferences.getKeys();
for(int i=0; i<keys.length ; i++){
bool value = sharedPreferences.getBool(keys.elementAt(i));
prefList.add(value);
}
If you have non bool value too in your persistent storage, you have to use the recognisable key to store those value.
For example :- sharedPreferences.setBool('bool${widget.id}', value);
Now this special keyword can be used to know if it is a bool value or not
List<bool> prefList = [];
var sharedPreferences = await SharedPreferences.getInstance();
Set<String> keys = sharedPreferences.getKeys();
for(int i=0; i<keys.length ; i++){
if(key.elementAt(i).contains('bool')){
bool value = sharedPreferences.getBool(keys.elementAt(i));
prefList.add(value);
}
}
Edit:- You have to use the code inside a function and return you string
Example:-
Future<List<bool>> getBoolList() async{
List<bool> prefList = [];
var sharedPreferences = await SharedPreferences.getInstance();
Set<String> keys = sharedPreferences.getKeys();
for(int i=0; i<keys.length ; i++){
bool value = sharedPreferences.getBool(keys.elementAt(i));
prefList.add(value);
}
return prefList;
}
Then call this function
List<bool> list = await getBoolList();
Note :- In simple words, only asynchronous functions will allow you to use await keyword inside them, and if they return something, that will be Future.

Related

flutter sqflite+getx use group_button to filter the array from database and render GridView.builder

I am using flutter desktop development. Use the group button filter to read data from the database and render it to GridView.builder().
At present, I can't realize the filtering function when I read the data sheet from the database[enter image description here][1]
I am using getx
final selected = 'table_operation'.obs;
final items = ['table_operation', 'merge_table', 'turn_table'];
final SqliteHelper _sqliteHelper = SqliteHelper();
final areas = [].obs;
final selectedAreaType = 0.obs;
final tables = [].obs;
// final filterTables = [].obs;
var areaModel;
final areaId = 0.obs;
void setSelected(value) {
selected.value = value;
}
void setSelectArea(int value) {
selectedAreaType.value = value;
areaModel = areas[selectedAreaType.value];
areaId.value = areaModel.id;
}
#override
onInit() {
getAreaList();
getTableList();
super.onInit();
}
Future<List<AreaModel>> getAreaList() async {
List<Map<String, dynamic>> results = await _sqliteHelper.queryObject('area');
List<AreaModel> areaList = [];
for (var r in results) {
if (r.isNotEmpty) {
areaList.add(AreaModel.fromMap(r));
}
}
areas.value = areaList.map((e) => e).toList();
return areaList;
}
Future<List<TableModel>> getTableList() async {
List<Map<String, dynamic>> results = await _sqliteHelper.queryObject('tables');
List<TableModel> tableList = [];
for (var t in results) {
tableList.add(TableModel.fromMap(t));
}
tables.value = tableList.map((e) => e).toList();
return tableList;
}
[1]: https://i.stack.imgur.com/fOGwg.png

Cannot get List data from SharedPreferences using FutureBuilder call

I have a String List in my shared preferences that's meant to store account numbers which can then be used to make a call from the API:
List<String> accountList = [];
Future _getListData() async {
SharedPreferences myPrefs = await SharedPreferences.getInstance();
for(var i = 0; i < myPrefs.getStringList('accounts').length; i++){
accountList.add(myPrefs.getStringList('accounts')[i]);
}
//prints values from shared preferences
print(accountList);
}
Future<List<dynamic>> fetchData() async {
_getListData();
//prints an empty list
print(accountList);
try {
if (accountList == null) {
var result = await http.get(apiUrl);
List<dynamic> accountInfo = (json.decode(result.body));
return accountInfo;
} else {
List<dynamic> accountInfo = [];
for(var i = 0; i < accountList.length; i++){
var result =
await http.get(apiUrl + "/api/Data/GetCustomer?accntnum=" + accountList[i]);
accountInfo.add(json.decode(result.body));
}
return accountInfo;
}
} catch (e) {
print(e);
}
}
When calling the Future function "fetchData()" from my FutureBuilder in the widget it returns an empty list. However within the scope of the "_getListData()" function it prints the list witht he appropriate values. How can I make it such that "fetchData()" gets the intended list?
Just add an await before _getListData() here:
Future<List<dynamic>> fetchData() async {
await _getListData();
//prints an empty list
print(accountList);

Change bool in initState flutter

I have a page with this code:
class _HomeScreenState extends State<HomeScreen> {
bool isFirstLoading = true;
#override
void initState() {
super.initState();
if (isFirstLoading) {
getInfo();
setState(() {
isFirstLoading = false;
});
} else {
getInfoFromSharedPref();
}
}
Future<http.Response> getInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Loader.show(context,
isAppbarOverlay: true,
isBottomBarOverlay: true,
progressIndicator: CircularProgressIndicator());
var url = kLinkAPI + "/getInfo";
var response =
await http.post(url, headers: {"Content-Type": "application/json"});
var resObj = jsonDecode(response.body);
if (response != null) {
setState(() {
if (resObj.length > 0) {
address = resObj[0]['address'];
countryInfo = resObj[0]['country_info'];
phone = resObj[0]['phone'];
latitude = resObj[0]['latitude'];
longitude = resObj[0]['longitude'];
isFirstLoading = false;
prefs.setString('address', address);
prefs.setString('countryInfo', countryInfo);
prefs.setString('phone', phone);
prefs.setString('latitude', latitude);
prefs.setString('longitude', longitude);
}
});
}
Loader.hide();
}
void getInfoFromSharedPref() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
address = prefs.getString('address');
countryInfo = prefs.getString('countryInfo');
phone = prefs.getString('phone');
latitude = prefs.getString('latitude');
longitude = prefs.getString('longitude');
});
}
}
I would like to make sure that the first time I enter the page, the isFirstLoading variable is set to false and then calls the getInfo function with the http call while if it is false it takes from the shared preferences.
isFirstLoading is now always true
how could I solve?
I think you're overcomplicating your code. Let me know if this solves your issue.:
class _HomeScreenState extends State<HomeScreen> {
SharedPreferences prefs;
#override
void initState() {
super.initState();
getInfo();
}
// ...
}
Now, the first time this widget is inserted into the tree:
initState() will be called once.
Therefore, getInfo() will be called. getInfo() will make the http call and update the prefs variable using setState, which you have already done.
Whenever the widget is reloaded, the prefs variable will not be lost since it is a stateful widget.
Next, if you would like to save the preference settings locally instead of making an http call every time the user opens the app, you should handle that inside of getInfo() itself. Something like this:
getInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (prefs.getBool("isFirstLoading") == false) {
// setState to update prefs variable
} else {
// make http call
// save prefs (optional)
// setState to update prefs variable
}
}
If I undestand correctly, you are trying to only call the getInfo method on the first load, and the getInfoFromSharedPref all the other time.
My suggestion is to save the isFirstLoading bool as a preference like so:
class _HomeScreenState extends State<HomeScreen> {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isFirstLoading = prefs.getBool("isFirstLoading") ?? true;
#override
void initState() async {
super.initState();
if (isFirstLoading) {
await getInfo();
await prefs.setBool("isFirstLoading", false);
isFirstLoading = false;
} else {
getInfoFromSharedPref();
}
}
Future<http.Response> getInfo() async {
// …
}
void getInfoFromSharedPref() async {
// …
}
}

How to save a list with SharedPreferences?

I tried to save a List (which is called test)with two variables with SharedPreferences. I tried the code below, but I get some errors. Does anybody see the mistake i made? (I think it´s kind of an easy to fix mistake, but I´m a beginner and can´t find it ;)
int counter1 = 0;
int counter2 = 20;
String nameKey = "eins";
var test = [counter1, counter2];
#override
void initState() {
super.initState();
}
Future<bool> save() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return await preferences.setIntList(nameKey, test);
}
Future<List<int>> load() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getIntList(nameKey);
}
set() {
load().then((value) {
setState(() {
test = value;
});
});
}
Thanks in advance :)
Future<List<String>> load() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getStringList(nameKey);
}

issue with geting all data from sqflite database

i have been trying to get all my data from a sqflite database, when i try to get a single data, this works totally fine:
Future<dynamic> getUser() async {
final db = await database;
var res = await db.query("files");
if (res.length == 0) {
return null;
} else {
var resMap = res[0];
return resMap;
}
}
but when i try to get all data using a for loop like the example below, i get an error
Future<dynamic> getUser() async {
final db = await database;
var res = await db.query("files");
var resMap;
var count = res.length;
if (count != 0) {
for (int i = 0; i < count; i++) {
resMap.add(res[i]);
}
}
return resMap;
}
the error says:
The method 'forEach' was called on null.
Receiver: null
Tried calling: forEach(Closure: (dynamic, dynamic) => Null)
i understand that it says that I've got no data,
and i also tried to remove the if statement, but still no luck!
change this method:
EDIT
Future<List<Map>> getUser() async {
final db = await database;
var res = await db.query("files");
List<Map> resMap = [];
if (res != null res.length > 0) {
for (int i = 0; i < count; i++) {
resMap.add(res[i]);
}
return resMap;
} else
{
return null;
}
}
try this in you widget
List<Map> newUser = [];
#override
void initState() {
super.initState();
getUser();
}
getUser() async {
final _userData = await DBProvider.db.getUser();
if(_userData != null ){
setState(() {
newUser = _userData;
});
} else{
setState(() {
newUser =[];
});
}
}