0

So I have an async funtion:

Future decodeToken() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  var token = await prefs.getString('token');
  final Map<String, dynamic> payload = json.decode(
    ascii.decode(
      base64.decode(base64.normalize(token.split(".")[1])),
    ),
  );
  return payload;
}

and when I try do do:

var payload = await decodeToken();

it throws an error saying "The await expression can only be used in an async function."

I tried taking out the "await" and print the payload variable but obviously it prints "Instance of Future"

if I do:

decodeToken().then((value)=>print(value)) 

it prints the value correctly, but I want to use it in a variable, how do I return the vvalue of an async function?

Christopher Moore
  • 15,626
  • 10
  • 42
  • 52
Marco Ramos
  • 107
  • 1
  • 8
  • Please do not edit answers into the question. If you have an answer, post an answer to your own question. Since, your question is closed as a duplicate, add an answer to the duplicate if you believe it will help future users. – Christopher Moore Mar 04 '21 at 15:44

2 Answers2

2

The error message is saying you can only use await in a method that is marked as async, so you are calling an asynchronous method from a synchronous one and Dart doesn't like that.

You have several options:

  1. Use the Future...then pattern:
Map<String, dynamic> payload;
decodeToken().then((data) {
  payload = data;
});
  1. Make the surrounding method async:
void foo() async {
  var payload = await decodeToken();
}
  1. Use a FutureBuilder (if you need your future's data in the build method):
Widget build(BuildContext context) {
  return FutureBuilder(
    future: decodeToken(),
    builder: (context, snapshot) {
      if (!snapshot.hasData) {
        // Future hasn't completed yet, display something in the meantime
        return CircularProgressIndicator();
      }
      // Future has completed, get data
      var payload = snapshot.data;
      ...
    },
  );
}
Abion47
  • 22,211
  • 4
  • 65
  • 88
0

Define the return type as Future<Map<String, dynamic>>

Future<Map<String, dynamic>> decodeToken() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  var token = await prefs.getString('token');
  final Map<String, dynamic> payload = json.decode(
    ascii.decode(
      base64.decode(base64.normalize(token.split(".")[1])),
    ),
  );
  return payload;
}

YoBo
  • 2,292
  • 3
  • 9
  • 25