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
Future
instead: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
await
the result, making them also asynchronous.If possible, make your class constructor private and force callers to obtain instances with an asynchronous, factory-like
static
method: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
currentUsername
to be asynchronous. A disadvantage is that a private constructor would prevent your class from being extended.If possible, I'd also make
getUsernameFS
astatic
method and pass the username to the private constructor. ThencurrentUsername
wouldn't need to belate
, and you would avoid any risk of accidentally using alate
variable before it's initialized.