How to wait for return to continue running the app? - Flutter

Asked

Viewed 70 times

0

I have a function retornaDescricao() which makes an http request and edits the variable controller with the received value. However, the value is only changed when I press the Elevatedbutton for the second time() .

import 'dart:convert';

import 'package:flutter/material.dart';

import 'package:http/http.dart' as http;

class AgregarUsuario extends StatefulWidget {
  @override
  _AgregarUsuarioState createState() => _AgregarUsuarioState();
}

class _AgregarUsuarioState extends State<AgregarUsuario> {
  TextEditingController controlNombre = new TextEditingController();
  TextEditingController controlTelefono = new TextEditingController();
  TextEditingController controlEmail = new TextEditingController();
  TextEditingController controlDescricao = new TextEditingController();

  Future retornaDescricao() async {
    var resposta;
    http.Response response;

    response = await http
        .get(Uri.parse("http://192.168.2.5/pruebas/obterDescricao.php"));
    resposta = json.decode(response.body);
    var lista = resposta;
    String descricao = lista[0]["nombre"];

    controlDescricao.text = descricao;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("AGREGAR USUARIO"),
      ),
      body: Container(
        padding: EdgeInsets.all(10.0),
        child: Center(
          child: Column(
            children: <Widget>[
              TextField(
                controller: controlNombre,
                decoration:
                    InputDecoration(labelText: "Código de barras - EAN"),
              ),
              TextField(
                controller: controlTelefono,
                keyboardType: TextInputType.number,
                decoration: InputDecoration(labelText: "Quantidade"),
              ),
              Padding(padding: EdgeInsets.all(16.0)),
              ElevatedButton(
                onPressed: () {
                  //agregarUsuario();
                  setState(() {
                    retornaDescricao();

                    print("texto recebido: " + controlDescricao.text);
                  });

                  agregarUsuario();
                  //Navigator.pushReplacementNamed(context, '/');
                },
                child: Text("Adicionar à impressão"),
              ),
              Container(
                  height: 35.0,
                  child: Text(
                    controlDescricao.text,
                    textAlign: TextAlign.center,
                    style: TextStyle(fontSize: 30.0),
                  ))
            ],
          ),
        ),
      ),
    );
  }

  void agregarUsuario() {
    //var url = "http://192.168.0.11/pruebas/agregarUsuario.php";
    if (controlNombre.text == null || controlNombre.text == "") {
    } else {
      http.post(Uri.parse("http://192.168.2.5/pruebas/agregarUsuario.php"),
          body: {
            "nombre": controlNombre.text,
            "telefono": controlTelefono.text,
            "email": controlEmail.text,
          });
    }
  }
}

Console return:

    Restarted application in 1.139ms.
    I/flutter ( 9135): texto recebido:
    2
    I/flutter ( 9135): texto recebido: 789000000000000

2 answers

1

The way you did, there are two ways out...

1st Form (Not the best)

Let the onPressed of Elevatedbutton async and await the return of Future, even though it’s void.

          ElevatedButton(
            onPressed: () async {
              //agregarUsuario();
              setState(() {
                await retornaDescricao();

                print("texto recebido: " + controlDescricao.text);
              });

              agregarUsuario();
              //Navigator.pushReplacementNamed(context, '/');
            },
            child: Text("Adicionar à impressão"),
          ),

2nd Form (Which is better in terms of organization)

Move the setState into the function retornaDescricao().

         ElevatedButton(
            onPressed: () {
              //agregarUsuario();
              retornaDescricao();
              agregarUsuario();
              //Navigator.pushReplacementNamed(context, '/');
            },
            child: Text("Adicionar à impressão"),
          ),

[...]

  Future retornaDescricao() async {
    var resposta;
    http.Response response;

    response = await http
        .get(Uri.parse("http://192.168.2.5/pruebas/obterDescricao.php"));
    resposta = json.decode(response.body);
    var lista = resposta;
    String descricao = lista[0]["nombre"];

    setState(() {
      controlDescricao.text = descricao;
      print("texto recebido: " + controlDescricao.text);
    }
  }

Note: In case you want to use the controlDescricao within the function agregarUsuario(), you will have to leave the click of the async button and use the await in the method call retornaDescricao().

Explanation

The way you did, does not wait for the end of the method call retornaDescricao(), so it calls the method and then immediately prints the old value of the variable.

I say that the first way is not the best, because inside a setState is not advised to do many operations, so use it only where actually set a final value (preferably already computed) that needs to be updated on screen.

If you want to take a look, I wrote an article on asynchronous functions...

Uncomplicated Flutter - Asynchronous Functions

0

You can use Future’s methods. then will be invoked when Future is solved. It’s good to use catchError also to handle possible request errors.

     ElevatedButton(
            onPressed: () {
              retornaDescricao()
               .then((_)=>{
                   setState(() {});
                   print("texto recebido: " + controlDescricao.text);
                   agregarUsuario();
                  //Navigator.pushReplacementNamed(context, '/');
               })
               .catchError((error) => print("Ops... algo deu errado"));
            },
            child: Text("Adicionar à impressão"),
          ),

Reference: https://api.dart.dev/stable/2.12.4/dart-async/Future-class.html

Browser other questions tagged

You are not signed in. Login or sign up in order to post.