1

I have a function that return a Future and I want to put it in a variable so that the value of the variable stays the same and can be used in other functions of the widget as long as the widget is not rebuilt.

This value is a sessionid, and I want to use it to access to webservices that are called in the "sub-widgets" of the widget. Right now I'm doing the whole authentification process to get the sessionid every time a webservice is called.

Here is what I tried :

    @override
  Widget build(BuildContext context)async{
    sessionid = await getSessionId();

But when I use async await my build method have to return a Future, but the build method actually can't return a Future so I'm kind of blocked here.

Any help would be appreciated,

Update :

I created this function to set the variable value :

setJsessionId()async {
var new_jsessionId = await getJsessionId();
setState(() {
  jsessionId = new_jsessionId;
});

} which I call here :

@override
  Widget build(BuildContext context){
    setJsessionId();

It works, but the problem is it keeps rebuilding the widget and calling the authentification function and the webservice eternally,

I call the webservice to build a reorderableListView and it keeps duplicating the results without stopping as such :

enter image description here

Here is the code of the FutureBuilder I am using to display this list :

child: FutureBuilder<List<Task>>(
          future:
            getTasks(),
          builder: (BuildContext context, AsyncSnapshot<List<Task>> snapshot){
            if(snapshot.hasError){
              return const Text('Erreur');
            }
            if(snapshot.hasData){
              return ReorderableListView(
                buildDefaultDragHandles: false,
                header: Center(
                  child: Container(
                    child: Text(
                      'Listes des tâches',
                      style: Theme.of(context).textTheme.headline5,
                    ),
                    padding: EdgeInsets.symmetric(vertical: 20)
                  )
                ),
                children: taskList.map((e) => ListTile(
                  key: UniqueKey(),
                  //leading: Icon(BeoticIcons.disc),
                  leading: Image.asset("assets/images/Task-Bleu_0.png", height: 30),
                  title: Text("Tache: " + e.name),
                  subtitle: Text("Projet: " + e.projectName),
                  //trailing: Icon(BeoticIcons.circle_check, color: Colors.green)
                  trailing: Wrap(
                    spacing: 5,
                    children: [
                      Image.asset("assets/images/Task-Validated_0.png", height: 30),
                      GestureDetector(
                        onTap: () {
                          Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => TaskInfoPage(task: e)
                            ),
                          );
                        },
                        child: Icon(BeoticIcons.simply_right, size: 28)
                      )
                    ]
                  )
                )).toList(),
                onReorder: _onReorder,   
              );
            }
            return const Center(child: CircularProgressIndicator());
          }
        )

Here is the Thanks,

JS1
  • 631
  • 2
  • 7
  • 23
  • Does this answer your question? [What is a Future and how do I use it?](https://stackoverflow.com/questions/63017280/what-is-a-future-and-how-do-i-use-it) – nvoigt Nov 02 '21 at 13:02

1 Answers1

1

Create one Future Method like,

setSessionId() async {
    sessionid = await getSessionId();
}

Call above function inside build,

    @override
    Widget build(BuildContext context) {
         setSessionId();

Or you can also use call setSessionId() inside initState() like below,

  @override
  void initState() {
    super.initState();
    setSessionId();
}
Yashraj
  • 1,025
  • 1
  • 5
  • 22
  • 1
    You would need at least a stateful widget and a call to setState({}) for this to work. – nvoigt Nov 02 '21 at 13:03
  • Thanks for your help guys, I tried it, it almost works but I'm getting duplicated results, see my update above – JS1 Nov 02 '21 at 14:09
  • Actually it was when calling the function in the build method that I got duplicated results, when I tried calling it in initState method it works fine. Also, @nvoigt is absolutely right, the update of the variable need to be encapsulate in a setState function. – JS1 Nov 02 '21 at 15:33