How to init state of widget variable with Future string in flutter - flutter

I have to initialise the state of widget variable with the value stored in StoredProcedure.
void initState() {
widget.query = fetchMake();
super.initState();
}
Future<String> fetchMake() async{
final prefs = await SharedPreferences.getInstance();
return prefs.getString(key);
query.toString();
}
But the issue is that it cant assign that value to query variable and showing error value to type future string cannot assign to string flutter
How can I do that?

fetchMake is async so you have to put await where you call that method but it will not work because you are calling it in initState.
So You have to assign widget.query variable value in that function only. Moreover, as you get data you have to call setState, so data you receive reflect in ui.
In addition to that you have to check query is null or not where you are using it because when first time build method call it will not have any data.
String query;
void initState() {
fetchMake();
super.initState();
}
fetchMake() async{
final prefs = await SharedPreferences.getInstance();
setState((){
query = prefs.getString(key) ?? 'default';
});
}

You can try:
String query;
void initState() {
super.initState();
fetchMake().then((value) {
setState(() {
query = value;
});
});
}
Future<String> fetchMake() async{
final prefs = await SharedPreferences.getInstance();
return prefs.getString(key);
}
1, You can not set state with widget.query.
2, Create a variable query on state of Widget.
3, fetchMake is a async function => using then to wait result.

Related

Flutter shared prefernce return NULL

I have next piece of flutter code, to get shared preference key-value
I do understand why _blueUriInit is always NULL
I assume that you are forgot to provide the value for that key before call to get its value, you need to first assign value to it first:
Future<bool> saveData(String key, dynamic value) async {
final prefs = await SharedPreferences.getInstance();
return prefs.setString(key, value);
}
and call it like this:
void initState() {
saveData('blueUri', 'test');
setState(() {
_blueUriInit = getValue('blueUri');
});
super.initState();
}
now next time you open your app, getValue should return you test.
you can create this function for setting value
static setUserID(String key, String value) async {
final SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.setString(key, value);
}
Use case :
await SharedValue.setUserID("Email", "demo#gmail.com");
And For getting value from shared preference you can use this function
static Future<String?> getUserID(String key) async {
final SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getString(key);
}
Use case :
userName = await SharedValue.getUserID("Email");
First you need to setString with key and value (name is key)
Future setValue() async {
final prefs = await SharedPreferences.getInstance();
prefs.setString("name", "Hitarth");
}
getString with key (here i took "name" as key)
Future getValue(String key) async {
final prefs = await SharedPreferences.getInstance();
String value = prefs.getString(key) ?? "NULL";
return value;
}
store in variable callin getValue
void initState() {
setState(() {
_blueUriInit = getValue("name");
});
super.initState();
}

Why am I getting 'Future<dynamic>' instead of the return value in the function?

I'm trying to get the return value in my function but the output is 'Instance of Future' instead of the value of school field name in the database
#override
void initState() {
userId = _auth.currentUser!.uid;
publisherSchool =
getName(widget.postInfo['publisher-Id'], 'school').toString();
super.initState();
}
Future getName(String publisherUid, String fieldname) async {
DocumentSnapshot publisherSnapshot = await FirebaseFirestore.instance
.collection('users')
.doc(publisherUid)
.get();
print(publisherSnapshot.get(fieldname));
return publisherSnapshot.get(fieldname);
}
but whenever i'm printing the publisherSnapshop.get(fieldname) i'm getting the correct value from the database
There are 2 ways to do it, you can create a Future method and call it inside the initState like below:
#override
void initState() {
initial();
super.initState();
}
Future<void> initial() async {
userId = _auth.currentUser!.uid;
// Remember using `()` to wrap the `await` to get it result
publisherSchool = (await getName(widget.postInfo['publisher-Id'], 'school')).toString();
}
Or you can use .then to call it directly inside the initState:
#override
void initState() {
userId = _auth.currentUser!.uid;
getName(widget.postInfo['publisher-Id'], 'school').then((value) {
publisherSchool = value.toString();
});
super.initState();
}
When you declare the getName() function, specify the return type as Future<String>, and then when you call getName(), you need to await the result e.g. publisherSchool = await getName(widget.postInfo['publisher-Id'], 'school').toString();
The reason why you are not getting the correct response is because whenever you are working with Futures it takes some time to finish and return the results. Meanwhile it is fetching the result you have to make it await so that the program will continue once that future function is complete since await/then is nowhere to be found in your code hence the issues.
To solve this make this change:
Change
publisherSchool =
getName(widget.postInfo['publisher-Id'], 'school').toString();
To
getName(widget.postInfo['publisher-Id'],
'school').then((value){
publisherSchool=value.toString()});

How can i always setState when the page is opened?

My issue is, when the page is opened my variable isn't set. So when i'm querying from firestore i get the error The method '[]' was called on null. Receiver: null Tried calling: []("userbio")
I declared 2 variables
var userid;
var useremail;
Then i wrote this future
Future getUserData() async {
var firestore = Firestore.instance;
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final String uid = user.uid.toString();
final String email = user.email.toString();
DocumentReference qn = await firestore
.collection("users")
.document(email)
.collection('userdetails')
.document(uid);
void initState() {
setState(() {
userid = uid;
useremail = email;
});
}
return qn.documentID;
}
This is how i'm currently trying to setState but it's not working
void initState() {
setState(() {
userid = uid;
useremail = email;
});
}
Please help, thanks.
comment if you need more context
Seems like you're declaring the nested function initState() but you're not calling it. I would just remove the function and call setState() directly :
...
.document(uid);
setState(() {
...
EDIT : Call getUserData() inside initState :
// In a class extending State<T>
#override
void initState() {
super.initState();
// synchronous call if you don't care about the result
getUserData();
// anonymous function if you want the result
() async {
var result = await getUserData();
}();
}
PS : initState(), like build() or setState(), is a predefined name in Flutter. Try not to use those names for functions that are not overriding the original ones.
Try assign your variable an empty value instead of leaving it null.
var userid = '';
var useremail = '';

Flutter: Save and Fetching multiple value in SharedPreferences

I'm working with SharedPreferences to make feature offline bookmark News . i can saved and fetching single value with this code :
Saved Value
void _testingSavePref(String judulBerita) async {
SharedPreferences pref = await SharedPreferences.getInstance();
pref.setString("tokenbookmark", judulBerita);
}
Fetching Value
#override
void initState() {
super.initState();
setState(() {
_testingLoadPref();
});
}
_testingLoadPref() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
tokenBookmark = pref.getString("tokenbookmark");
});
}
Everything is oke , but it's possible to saved and fetching multiple value with SharedPreferences ?
Example, i have 2 or more data, i want all data saved and not overwrite.
Thank's
Updated Code:
For Saving Values
void _testingSavePref(List<String> judulBerita) async {
SharedPreferences pref = await SharedPreferences.getInstance();
await pref.setStringList("tokenbookmark", judulBerita); //judulBerita is a list of string now
}
For Fetching Values
#override
void initState() {
super.initState();
setState(() {
_testingLoadPref();
});
}
_testingLoadPref() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
final List<String>? tokenBookmark = pref.getStringList("tokenbookmark");
});
}
Now, You can get the data from tokenBookmark list by below code
for(String s in tokenBookmark){
print(s);
}
You shouldn't use SharedPreferences to save that kind of data.
Use a local sql or nosql database (sqflite / sembast).
Also don't call setState inside the initState method is wrong and unnecessary.

Instance of 'Future<String>' instead of showing the value

Iam using flutter and I am trying to get a value from shared_preferences that I had set before, and display it in a text widget. but i get Instance of Future<String> instead of the value. here is my code:
Future<String> getPhone() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String patientPhone = prefs.getString('patientPhone').toString();
print(patientPhone);
return patientPhone;
}
Future<String> phoneOfPatient = getPhone();
Center(child: Text('${phoneOfPatient}'),))
There is await missing before prefs.getString( and use setState() instead of returning the value. build() can't use await.
String _patientPhone;
Future<void> getPhone() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String patientPhone = await /*added */ prefs.getString('patientPhone');
print(patientPhone);
setState(() => _patientPhone = patientPhone);
}
build() {
...
Center(child: _patientPhone != null ? Text('${_patientPhone}') : Container(),))
}
If you don't have the option to use await or async you can do the following.
getPhone().then((value){
print(value);
});
and then assign a variable to them. From that, you'll have the result from the value.