I’ve assigned a value for a local variable inside a function (Future
), but the result always gives a null
value. Is there any wrong code in my code?
enum StatusUser { telahMasuk, belumMasuk, berhasilMasuk, gagalMasuk }
class MyClass {
Future<StatusUser> muatSeting(String? key) async {
StatusUser? sp;
final data = await getUserData();
try {
if (data != null) {
final dataToken = jsonDecode(
APIUser().decodeJWT(data['token'].toString().split('.')[1]));
if (new DateTime.now().millisecondsSinceEpoch -
dataToken['tgl_verify'] <
864000) {
sp = StatusUser.telahMasuk;
}
} else {
sp = StatusUser.belumMasuk;
}
} catch (e) {
print(e);
}
return sp!;
}
}
When I debugging, its shows _CastError (Null check operator used on a null value)
. Whereas at previous version of Flutter, it works. I want that this future
returning an enum value from variable sp
.
❯ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.7.7, on Ubuntu 22.04.2 LTS 5.19.0-38-generic, locale id_ID.UTF-8)
Checking Android licenses is taking an unexpectedly long time...[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[!] Android Studio (not installed)
[✓] VS Code (version 1.76.2)
[✓] Connected device (3 available)
[✓] HTTP Host Availability
3
Answers
I've solved it with adding
else
on nestedif
I'm in confuse with 'why nested if (child) when without else and false condition dosen't returning value that was set on else from parent if'
The null check operator is failing here because
sp
is null.Looking from the if statement, I think this condition fails
(new DateTime.now().millisecondsSinceEpoch - dataToken['tgl_verify'] < 864000)
and thereforesp
is never set.If you want
StatusUser.belumMasuk
to be returned by default, then you either should initializesp
to use that as its default value:or use the
??
operator:Both cases would allow you to remove the
else
blocks and additionally would handle the case where an exception is thrown within thetry
block. (Incidentally, you should avoidcatch
es withouton
clauses.)In your answer, you made a remark:
Why would it? That’s not how
if
–else
works. The outerelse
block corresponds only to the outerif
condition.Imagine:
If
condition2
isfalse
, do you expectdoLotsOfOtherStuff()
to be skipped? But if so, thendoLotsOfOtherStuff()
should be moved to be within theif (condition2)
block. Do you expectdoLotsOfOtherStuff()
andhandleCondition1Failed()
to both be executed? Either of those choices would be unintuitive and very hard to follow for most people.If you want the
else
block to be executed if eithercondition1
orcondition2
fails, then you should write it as: