title: How can I use Provider for async data? (Flutter)
body: <h1>Background</h1>
  
  <p>I am building super simple TODO list app for practicing Flutter. If you input a string and click "add", then the text is shown in the list on the upper part.</p>
  
  <h1>Question</h1>
  
  <p>When and how should I call <code>model.getTasks()</code> (= update data asynchronously) and <code>model.refresh()</code> (= <code>notifyListeners</code>)? </p>
  
  <p>I find the list is not updated immediately because I don't use <code>await</code> for <code>model.getTasks()</code>. I tried these but I would like to know if there are better ways.  </p>
  
  <ul>
  <li>Use <code>await model.getTasks()</code> and make <code>build</code> an async function. --> Compile error</li>
  <li>Add <code>await model.getTasks()</code> right before <code>model.refresh()</code>. --> <code>model.tasks</code> is not updated before rendering <code>ListView</code> when opening the app. <code>model.getTasks()</code> are called twice when creating new tasks.</li>
  </ul>
  
  <h1>Screenshot</h1>
  
  <p><a href="https://i.stack.imgur.com/ubKJJ.png" rel="noreferrer"><img src="https://i.stack.imgur.com/ubKJJ.png" alt="App TODO list page"></a></p>
  
  <h1>Code details</h1>
  
  <ul>
  <li><code>model.tasks</code> is <code>List&lt;Task&gt;</code>, which is to store tasks fetched from DB (<code>sqflite</code>).</li>
  <li><code>model.getTasks()</code> is an async function to fetch data from DB and overwrite <code>model.tasks</code>.</li>
  <li><code>model.refresh()</code> is only for calling <code>notifyListeners()</code>.</li>
  <li><code>TodoListPage</code> is the listener of the model's <code>notifyListeners</code>.</li>
  </ul>
  
  <pre><code>class TodoListPage extends StatelessWidget {
    final TextEditingController _textFieldController = TextEditingController();
  
    @override
    Widget build(BuildContext context) {
      print('TodoListPage.build');
      final model = Provider.of&lt;TodoListModel&gt;(context);
      model.getTasks();
  
      Future createTask() async {
        TaskData taskData = await DatabaseHandler()
            .insertTask(new TaskData(name: _textFieldController.text));
        model.refresh();
      }
  
      return Scaffold(
        appBar: AppBar(
          title: Text(
            'TODO List',
          ),
        ),
        body: Column(
          children: &lt;Widget&gt;[
            Container(
              height: 150,
              child: ListView.builder(
                itemBuilder: (BuildContext context, int index) {
                  return Text(model.tasks[index].name);
                },
                itemCount: model.tasks.length,
              ),
            ),
            Text(
              'Add',
            ),
            Form(
              child: Column(
                children: &lt;Widget&gt;[
                  TextFormField(
                    controller: _textFieldController,
                  ),
                  RaisedButton(
                    onPressed: () {
                      print('onPressed');
                      print(_textFieldController.text);
                      createTask();
                    },
                    child: Text('New'),
                  ),
                ],
              ),
            )
          ],
        ),
      );
    }
  }
  </code></pre>