Conditional with async in flutter

Asked

Viewed 314 times

1

I have the following function, which returns me either "FREE" or "PREMIUM". The return of the database works perfectly. Here is the code.

userInfoConst() async {
    try {
      var uid = await AuthenticationProvider().getUserId();
      ApiProvider apiProvider = ApiProvider();
      final usuarioModel =
          await apiProvider.getRequest('usuarios/$uid');
      UsuarioModel model = UsuarioModel.fromJson(usuarioModel.data);
      var plano =  model.plano;
      print(plano);
      return plano;
  }

What I intend to do is make the following parole:

if (ApplicationConsts().userInfoConst() == 'FREE') {
      _banner
        ..load()
        ..show(anchorType: AnchorType.bottom);
    }

The problem is that it never enters the code within the conditional, even though the condition is met.

After much debug and research I discovered the following: - It is not possible to make an "asynchronous conditional", that is, you cannot use async/await together in if. - The value that is returned from my function does not arrive in time to make the comparison with the string 'FREE', so it never enters.

I have tried using Futurebuilder, but it did not work. I have tried to put my function inside initState but also without success. I still believe you have the futureBuilder wrong...

How can I solve this problem?

  • 1

    I don’t know where you are making this comparison but you have already tried to "solve" the asynchronous method before making the comparison? var info = await ApplicationConsts().userInfoConst() would take the result, after you are with it compares if(info == "FREE") { ... }.

  • @Leonardopaim I make the comparison within the widget build. There’s no way to await it directly as you mentioned. I would have to use it in a method with async. I’ve tried that too, but without success. So in a way I tried that when you said

  • I even imagined that you were doing inside the widget anyway, as you did not give the executable code to test I quoted something as superficial as possible... could you provide a functional example of your code? One that can be taped to Dartpad just to make it easier for everyone.

  • @Leonardopaim the code is on the company computer, so it will not be available now...

2 answers

2

Using a FutureBuilder may wait until the method is processed.

Example

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: userInfoConst(),
      builder: (context, snapshot) {
        // Caso não tenha dados renderiza algo
        // um loading por exemplo...
        if (!snapshot.hasData) {
          return Center(
            child: CircularProgressIndicator(),
          );
        }

        // Quando processar será possível utilizar o
        // resultado do Future... Aqui usei apenas um ternário
        // para exemplo...
        return Container(
          color: snapshot.data == "FREE" ? Colors.amber : Colors.red,
        );
      },
    );
  }

  // Seu método de consulta ao banco de dados...
  userInfoConst() async {
    // Simula um delay de processamento de 2 segundos
    await Future.delayed(Duration(seconds: 2));

    return "FREE";
  }
}

The code can be tested on Dartpad.

1

The solution I found was this one. I want to thank everyone who put here their collaboration.

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
    buildWidget();
  }

  buildWidget() {
    ApplicationConsts().userInfoConst().then((value) {
      setState(() {
        if (value == "FREE") {
         _banner
        ..load()
        ..show(anchorType: AnchorType.bottom);
        } 
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(),
      ),
    );
  }
}

Browser other questions tagged

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