0

I have a code like this:

  String? _token;
  DateTime? _expiryDate;
  String? _userId;
  Timer? _authTimer;

  Future<bool> tryAutoLogin() async {
    final prefs = await SharedPreferences.getInstance();
    if (!prefs.containsKey('userData')) {
      return false;
    }
    final extractedUserData =
        json.decode(prefs.getString('userData')) as Map<String, Object>;// FIRST ERROR
    final expiryDate = DateTime.parse(extractedUserData['expiryDate']);// SECOND ERROR

    if (expiryDate.isBefore(DateTime.now())) {
      return false;
    }
    _token = extractedUserData['token']; //THIRD ERROR
    _userId = extractedUserData['userId']; // THIRD ERROR
    _expiryDate = expiryDate;
    notifyListeners();
    _autoLogout();
    return true;
  }

But it gives me these errors:

The argument type 'String?' can't be assigned to the parameter type 'String'.

The argument type 'Object?' can't be assigned to the parameter type 'String'.

A value of type 'Object?' can't be assigned to a variable of type 'String?'. Try changing the type of the variable, or casting the right-hand type to 'String?'.

I found this code from a Flutter tutorial and tried to fix the errors by adding ? or ! marks after some variable types but it seems I couldn't do that well.

EDIT: By updating this line of the code

final extractedUserData = json.decode(prefs.getString('userData')) as Map<String, Object>;

to

final extractedUserData = json.decode(prefs.getString('userData')) as Map<String, dynamic>;

The first error still exists but the other errors gone. I also tried to update the line like

final extractedUserData = json.decode(prefs!.getString('userData')) as Map<String, dynamic>;

(changed prefs to prefs!) but couldn't help, and I don't know how to fix it?

  • 1
    FWIW json.decode() returns a Map. I'm not sure what benefit comes from casting it to a Map... it seems like it would make it harder to work with. Your first error is because prefs.getString() can evaluate to null and json.decode() can't take null under nullsafety. If you test for null upstream you can use a `!` to force evaluation as type, otherwise you need to handle `prefs['userData']` potentailly containing a null. The second error can be solved with a cast of `...ryDate'] as String` but you'll need to address the same nullsafety issue with `['expiryDate']` – Pat9RB Sep 29 '21 at 16:21
  • @Pat9RB: I don't know about using object instead of dynamic, I am only following the tutorial. After I restarted my VS code it seems the other errors gone except the first one. I don't know where should I put the `!` mark because using it like `final extractedUserData = json.decode(prefs!.getString('userData')) as Map;` Doesn't work. –  Sep 29 '21 at 16:58
  • @Pat9RB: I noticed that I said something wrong in my previous comment. In fact changing `object` to `dynamic` in the line you mentioned resolved the rest of the errors. But still I have the first error as I said in my previous comment. –  Sep 29 '21 at 17:10
  • Also using `...ryDate'] as String` doesn't work if I try to keep `Map` –  Sep 29 '21 at 17:38
  • @Pat9RB: I think I could find the problem finally. –  Sep 29 '21 at 21:24

1 Answers1

0

Regarding to @ comment's I updated my code like below and it resolved all the errors:

  String? _token;
  DateTime? _expiryDate;
  String? _userId;
  Timer? _authTimer;

  Future<bool> tryAutoLogin() async {
    final prefs = await SharedPreferences.getInstance();
    if (!prefs.containsKey('userData')) {
      return false;
    }
    final extractedUserData = json.decode(prefs.getString('userData') as String)
        as Map<String, Object>;
    final expiryDate =
        DateTime.parse(extractedUserData['expiryDate'] as String);

    if (expiryDate.isBefore(DateTime.now())) {
      return false;
    }
    _token = extractedUserData['token'] as String;
    _userId = extractedUserData['userId'] as String;
    _expiryDate = expiryDate;
    notifyListeners();
    _autoLogout();
    return true;
  }