Home > Back-end >  Flutter jsonDecode FlutterSession value is not loading in widget initially. but works on hotload
Flutter jsonDecode FlutterSession value is not loading in widget initially. but works on hotload

Time:07-20

i am initializing a variable with value from session. but could not print it in the widget. but it is showing after hot load. here is my code :

 class _dashboardState extends State<dashboard> {
  var logindata;
  @override
  initState() {
    super.initState();

    _getSession() async {
      logindata = jsonDecode(await FlutterSession().get("login_data"));
    }

    _getSession();
  }
@override
  Widget build(BuildContext context) {
    print(logindata); // prints null
    }

}

Instead of jsonDecode(await FlutterSession().get("login_data"))
if i add any random string or number like
logindata = "Session value";
it prints normally. otherwise on hot load only i am getting the session value. what will be the reason? please do help :(. i am new to flutter. After following ideas from the comments i have updated the code as follows:

class _dashboardState extends State<dashboard> {
  var logindata;

  @override
  void initState() {
    getSessionValue().then((logindata) {
      setState(() {
        logindata = logindata;
      });
    });
    super.initState();
  }

  Future<void> getSessionValue() async {
    logindata = jsonDecode(await FlutterSession().get("login_data"));

    return logindata;
  }
@override
  Widget build(BuildContext context) {
    print(logindata); // first prints null then correct array without hotload.
    }
}

here i got first null, then the correct value. but in my case i need the value of an object in the array logindata, that is logindata["shop_name"] . so in that case i am getting error The method '[]' was called on null. Receiver: null Tried calling: []("shop_name") . What do i do now ? i am really stuck here. :(

CodePudding user response:

Let me explain this first,

lifecycle of State goes like this createState -> initState ->........-> build

so you're right about the order of execution

you're calling getSessionValue() from initState and expecting widget to build right after it, but since getSessionValue() returns a Future after awaiting, the execution continues and builds the widget not waiting for the returned Future value from getSessionValue(), so it prints null initially, and then when the Future is available youre calling setState and it prints the actual value

there is no notable delay here but the execution flow causes it to behave like this

so what's the solution?... Here comes FutureBuilder to the rescue

it is possible to get different states of a Future using FutureBuilder and you can make changes in the UI accordingly

so in your case, inside build, you can add a FutureBuilder like this,

  FutureBuilder(
          future:  getSessionValue(),
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none: return Text("none");
              case ConnectionState.waiting: return Text("waiting");
              case ConnectionState.active: return Text("active");
              case ConnectionState.done:  
                   print(logindata); // this will print your result
                   return Text("${logindata}");
            }
          })

keep in mind that the builder should always return a widget

as the async operation is running, you can show the progress to the user by showing the appropriate UI for different states

for eg: when in ConnectionState.waiting, you can show/return a progress bar

Hope this helps, Thank you

CodePudding user response:

That is a normal behaviour since you are having an async function to get the login data (so it will take some time to be there) while the widget will be building , then build method will get executed first which will make the print executed with no data and then when you hot reload it will be executed perfectly , so if you you want to print it right after you get the data you can make the function this way :

 _getSession() async {
logindata = jsonDecode(await FlutterSession().get("login_data")).then((value) {print(value);});  }
  • Related