2

I am trying to complete this app that shows the exchange rates for specific cryptocurrencies by calling an async function. I try to display the exchange rate as a property in a seperate stateless widget.

The argument type 'Future<String>' can't be assigned to the parameter type 'String'.

This is how I am trying to use it.

How can I make this work?

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(' Coin Ticker'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Column(
            children: [
              TheEntireCard(
                output: getExchange('BTC'),
              ),
              Padding(
                padding: const EdgeInsets.fromLTRB(18.0, 18.0, 18.0, 0),
                child: Card(
                  color: Colors.lightBlueAccent,
                  elevation: 5.0,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(10.0),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.symmetric(
                        vertical: 15.0, horizontal: 28.0),
                    child: Text(
                      '1 BTC = $rate $selectedCurrency',
                      textAlign: TextAlign.center,
                      style: const TextStyle(
                        fontSize: 20.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.fromLTRB(18.0, 18.0, 18.0, 0),
                child: Card(
                  color: Colors.lightBlueAccent,
                  elevation: 5.0,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(10.0),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.symmetric(
                        vertical: 15.0, horizontal: 28.0),
                    child: Text(
                      '1 BTC = $rate $selectedCurrency',
                      textAlign: TextAlign.center,
                      style: const TextStyle(
                        fontSize: 20.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
          Container(
            height: 150.0,
            alignment: Alignment.center,
            padding: const EdgeInsets.only(bottom: 30.0),
            color: Colors.lightBlue,
            // For iOS, use the cupertino picker to achieve that iOS specific look on the scroller. https://docs.flutter.dev/development/ui/widgets/cupertino
            child:
                Platform.isIOS ? getCupertinoPickerItems() : getDropDownItems(),
          )
        ],
      ),
    );
  }

Future<String> getExchange(String cryptoName) async {
    var theText;
    try {
      final String data = await CoinData().getExchangeData( //<--getting data from crypto api
        theCurrency: selectedCurrency, // 
        theCryptoName: cryptoName,
      );
      setState(() {
        rate = data;
        theText = '1 $cryptoName = $rate $selectedCurrency';
      });
    } catch (e) {
      print(e);
    }
    return theText;
  }


class TheEntireCard extends StatelessWidget {
  const TheEntireCard({
    Key? key,
    required this.output,
  }) : super(key: key);
  final String output;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(18.0, 18.0, 18.0, 0),
      child: Card(
        color: Colors.lightBlueAccent,
        elevation: 5.0,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10.0),
        ),
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 15.0, horizontal: 28.0),
          child: Text(
            output,
            textAlign: TextAlign.center,
            style: const TextStyle(
              fontSize: 20.0,
              color: Colors.white,
            ),
          ),
        ),
      ),
    );
  }
} 





Ethan
  • 23
  • 1
  • 7

1 Answers1

1

In an async function the return type it's a Future.

You can add an await in front of the call, as: await getExchange('BTC') and that will return a String instead of a Future<String>.

But you cannot call an async function into the build(). That's why you should use a FutureBuilder. An example:

//The code you had above TheEntireCard

FutureBuilder<String>(
  future: getExchange('BTC'),
  builder:
      (BuildContext context, AsyncSnapshot<String> snapshot) {
    if (snapshot.hasData) {
      final theText = snapshot.data 
      TheEntireCard(
            output: theText ?? "",
          ),
    }
    return const CircularProgressIndicator() //While awaiting show the loading indicator
  },
),

//The code you had under TheEntireCard
Dani3le_
  • 1,257
  • 1
  • 13
  • 22