I was trying to add two numbers say point1 and point2. These points are stored in SharedPreferences .
I have fetched the points using a function Future<int> fetchPoints which is in below.
Then I called this from another function
fetchPoints:
Future<int> fetchFromSps(String field) async {
SharedPreferences sp = await SharedPreferences.getInstance();
return sp.getInt(field);
}
GetPoints:
Future<void> setPoints() async{
int _newPoints=await ((await fetchFromSps('point1'))+(await fetchFromSps('point2')));
setState(() {
_totalPoints=_newPoints.toString();
});
}
setInSharedPreference:
void setInSharedPreference() async{
SharedPreferences prefs=await SharedPreferences.getInstance();
prefs.setInt('point1', 0);
prefs.setInt('point2',0);
}
The function setInSharedPreference is in another dart file,which contains main function
I need to add two points which is named 'point1 and 'point2' from shared preference
just call them from any method like this sample:
fetchTwoPoints() async {
final point1 = await fetchFromSps("point1");
final point2 = await fetchFromSps("point2");
setState(() {
_totalPoints= (point1 + point2).toString();
});
}
Update your setInSharedPreference method because you are using async you need to wait to store the data.
Future<void> setInSharedPreference() async{
SharedPreferences prefs=await SharedPreferences.getInstance();
await prefs.setInt('point1', 0);
await prefs.setInt('point2',0);
}
Related
I have tried the answers in here How do you build a Singleton in Dart?
but I can't achieve what I want. so basically I want to make a Shared Preference Service as a singleton class. currently my code is like this. this is just a regular class, not a singleton.
class SharedPreferenceService {
late SharedPreferences _prefs;
SharedPreferenceService() {
SharedPreferences.getInstance().then((value) => _prefs = value);
}
Future<void> setIntroPagesHaveBeenViewed() async {
await _prefs.setBool(SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED, true);
}
Future<bool> checkIfIntroPagesHaveBeenViewed() async {
return _prefs.getBool(SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED) ?? false;
}
}
I need a singleton class, but when the instance is initialize for the first time, I also need to initialize _pref , so then I can access that _pref on the methods
Your problem is that initialization is asynchronous.
That means that the first time the singleton instance is accessed, that access needs to be asynchronous too (and so does any further access which happens before the initialization completes). However, the usage pattern of a singleton like this is such that you don't know which access is the first. So you have to make every access asynchronous.
Example:
class SharedPreferenceService {
static final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
Future<void> setIntroPagesHaveBeenViewed() async {
await (await _prefs).setBool(
SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED, true);
}
Future<bool> checkIfIntroPagesHaveBeenViewed() async {
return (await _prefs).getBool(
SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED) ?? false;
}
}
If all the methods are asynchronous anyway, that extra delay is not going to be a problem.
If you really, really only want to do that extra await if absolutely necessary,
you can cache the value, like you try to here:
class SharedPreferenceService {
static final Future<SharedPreferences> _prefsFuture = SharedPreferences.getInstance();
static SharedPreferences? _prefs;
Future<void> setIntroPagesHaveBeenViewed() async {
var prefs = _prefs ??= await _prefsFuture;
await _prefs.setBool(
SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED, true);
}
Future<bool> checkIfIntroPagesHaveBeenViewed() async {
var prefs = _prefs ??= await _prefsFuture;
return _prefs.getBool(
SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED) ?? false;
}
}
I retrieve an integer from SharedPreferences and I need to sum this value with another integer, but when I run the method I get an infinite loop with the sum.
I am calling the updateScore method to get a value that was saved before in SharedPreferences then I change the value with updateScore method, I save the value in SharedPreferences with saveScore method and I show the value in a Text().
int currentScore;
final int earnedScore;
#override
Widget build(BuildContext context) {
updateScore();
setScore();
return....
}
Future<int> getScore() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getInt(widget.keyNameScore);
}
Future<void> saveScore(int score) async{
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setInt(widget.keyNameScore, score);
}
void updateScore() async{
getScore().then((value){
currentScore = value;
currentScore = currentScore + earnedScore;
saveScore(currentScore);
});
}
void setScore(){
getScore().then((value){
setState(() {
currentScore = value;
});
});
}
I had to move my methods from the build to initState.
Hi I'm having issue where getting the stored value from Shared Preference and displaying it. It giving Future doesn't contain length instance error. My code below.
Save Shared Preference Value Code
Future<String> saveSearchQuery(String squery) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if(prefs.getStringList("searchhistory") == null){
final List<String> recentSearch = [];
recentSearch.insert(0, squery);
prefs.setStringList("searchhistory", recentSearch);
}else{
final recentSearch = prefs.getStringList("searchhistory");
if(recentSearch.contains(squery)){
recentSearch.forEach((e) => print(e));
}else{
recentSearch.insert(0, squery);
}
prefs.setStringList("searchhistory", recentSearch);
}
return prefs.commit().toString();
}
Get Shared Preference Value Code
Future<dynamic> getSearchHistory() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List searchHistory = prefs.getStringList("searchhistory");
return searchHistory.toList();
}
Please help. Thank you.
I am still a beginner on dart flutter, now I am trying to retrieve data from the REST API and socket.IO. at this time I have a confusing problem, I have tried searching on the internet for 3 days, but there is no solution. I have async and await scripts, but the function I added await doesn't give any response and still pause.
it is assumed that I have two different files, the first is the main file and the second is the helper file.
main.dart
Future<List<ChatTile>> fetchChat(socketutil,id) async {
socketutil.join(id); //STACK IN HERE
SharedPreferences prefs = await SharedPreferences.getInstance();
String messagePrefs = prefs.getString('messagePrefs');
print("DUA");
return await compute(parseListChat, messagePrefs);
}
helper.dart
Future<void> join(String id_room) async {
String jsonData ='{"room_id" : "$id_room","user_id" : "5a91687811138e74009839c9","user_name" : "Denis Muhammad Ramdan","user_photo" : "photo.jpg","user_status" : "1"}';
socketIO.sendMessage("join", jsonData, null);
//subscribe event
return await socketIO.subscribe("updateMessageList", (result) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('messagePrefs', result);
print('SATU');
return await result;
});
}
my question is there something wrong with my code, and how is the best way?
many thanks,
I suggest you to add await_only_futures to your analyzer config
analysis_options.yaml
lint:
rules:
- await_only_futures
You also don't need to do return await something since your function already return a future, this is redondant.
And from what I see of the socketio subscribe method, it does not return the result like you expect but use a callback and does not return it (https://pub.dartlang.org/documentation/flutter_socket_io/latest/flutter_socket_io/SocketIO/subscribe.html)
to handle this you should use a Completer
final completer = Completer<String>()
socketIO.subscribe("updateMessageList", (result) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('messagePrefs', result);
socketIO.unSubscribe("updateMessageList");
completer.complete(result);
});
return completer.future;
you probably want to handle error when there is using completer.completeError(error)
Update
You can alos convert the subscription to a Dart Stream to handle more case.
StreamController<String> controller;
Stream<String> get onUpdateMessageList {
if (controller != null) return controller.stream;
constroller = StreamController<String>.broadcast(
onCancel: () => socketIO.unSubscribe("updateMessageList"),
);
socketIO.subscribe("updateMessageList", constroller.add);
return controller.stream;
}
Future<StreamSubscription> join(String id_room) async {
...
return onUpdateMessageList.listen((result) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('messagePrefs', result);
});
}
I've seen this already: https://stackoverflow.com/a/49146503/1757321
Followed the solution, but it is not working in my case.
Some enlightenment would do for me this afternoon
Future<String> loadInterest() async {
print('Going to load interests');
final whenDone = new Completer();
SharedPreferences prefs = await SharedPreferences.getInstance();
final token = await prefs.getString('token');
print('The token ${token}');
await this.api.interests(token).then((res) {
// print('The response: ${res['interests']}'); <-- this prints response alright. Data is coming.
whenDone.complete(res['interests']);
});
return whenDone.future;
}
Then I'm trying to use the above Future in a future builder like so:
new FutureBuilder(
future: loadInterest(),
builder: (BuildContext context, snapshot) {
return snapshot.connectionState == ConnectionState.done
? new Wrap(
children: InterestChips(snapshot.data),
)
: Center(child: CircularProgressIndicator());
},
),
Where InterestChips(...) is this:
InterestChips(items) {
print('Interest Chips ${items}');
List chipList;
for (Object item in items) {
chipList.add(Text('${item}'));
}
return chipList;
}
But, I always get null as the snapshot, which means the loadInterest() for the Future is not returning anything.
If I understand this answer correctly, then I'm doing mine along the lines of that: https://stackoverflow.com/a/49146503/1757321
You don't need to use a Completer for this. Since your method is already async, you should just do this for your first code block:
Future<String> loadInterest() async {
print('Going to load interests');
final whenDone = new Completer();
SharedPreferences prefs = await SharedPreferences.getInstance();
final token = await prefs.getString('token');
print('The token ${token}');
final res = await this.api.interests(token).then((res) {
// print('The response: ${res['interests']}'); <-- this prints response alright. Data is coming.
return res['interests']);
}
You might also want to check for snapshot.hasError to make sure you're not getting any exceptions in there.