I have a file called database.dart. In it, I have a string property called currentUsername. This is the currently logged in user's username. I want this class to call the getUsernameFS() function only once and then be able to reuse this string for the rest of the class's existence inside its other functions. How do I accomplish this?
The code below gives an error: Error: A value of type 'Future<String>' can't be assigned to a variable of type 'String'.
class Database {
late String currentUsername = getUsernameFS(); //ERROR IS HERE
Future<String> getUsernameFS() async {...}
String someFunction() {...//some function that uses currentUsername//...}
}
CodePudding user response:
First of all, create init() method in your class to call getUsername function once.:
class Database {
String currentUsername;
Future<String> getUsernameFS() async {...}
void init() {
currentUsername = getUsernameFS();
}
String someFunction() {...//some function that uses currentUsername//...}
}
Keep in mind that the getUsernameFS() is returning a Future<String> and you cannot assign it to a variable of type String directly. To fix this use async/await combination:
void init() async {
currentUsername = await getUsernameFS();
}
To handle errors in future:
void init() {
getUsernameFS().then((username) {
currentUsername = username;
}).catchError((e) {
print(e);
});
}
Good luck!
CodePudding user response:
A couple of other options:
Make your member variable a
Futureinstead:Future<String> currentUsername = getUsernameFS();This has the advantage of safely avoiding accidental errors from callers who neglect to explicitly call some asynchronous initialization method first. However, this has the disadvantage of forcing all callers to
awaitthe result, making them also asynchronous.If possible, make your class constructor private and force callers to obtain instances with an asynchronous, factory-like
staticmethod:class Database { Database._(); static Future<Database> create() async { var db = Database._(); db.currentUsername = await db.getUsernameFS(); return db; } ... }This also has the advantage of safely avoiding accidental errors, and it avoids forcing all consumers of
currentUsernameto be asynchronous. A disadvantage is that a private constructor would prevent your class from being extended.If possible, I'd also make
getUsernameFSastaticmethod and pass the username to the private constructor. ThencurrentUsernamewouldn't need to belate, and you would avoid any risk of accidentally using alatevariable before it's initialized.
