Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: The operator '[]' isn't defined for the class 'Future<dynamic>'

I am getting the following error for my weather app. How can I fix it?

Compiler message: lib/loadingscreen.dart:38:41: Error: The operator '[]' isn't defined for the class 'Future'.

  • 'Future' is from 'dart:async'. Try correcting the operator to an existing operator, or defining a '[]' operator.

String weathericonlink = weatherdata['current']['condition']['icon'];

main file:

import 'package:flutter/material.dart';

import 'loadingscreen.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.dark(),
      home: LoadingScreen(),
    );
  }
}

the loadingscreen class is :

import 'dart:async';
import 'dart:convert';

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

class LoadingScreen extends StatefulWidget {
  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}

class _LoadingScreenState extends State<LoadingScreen> {
  Future<dynamic> getData() async {
    String url;
    var weatherdata;
    url =
        'https://api.weatherapi.com/v1/current.json?key=${apikey}&q=51.509865,-0.118092';

    http.Response response = await http.get(url);

    if (response.statusCode == 200) {
      String data = response.body;
      weatherdata = jsonDecode(data);
      print(weatherdata);
    } else {
      print(response.statusCode);
    }

    double temp = weatherdata['current']['temp_c'];
    print('Temperature: $temp');

    return weatherdata;
  }

  String getCurrentWeatherIcon() {
    var weatherdata = getData();

    String weathericonlink = weatherdata['current']['condition']['icon'];
    weathericonlink = weathericonlink.substring(35, weathericonlink.length);
    weathericonlink = 'assets/weathericons/$weathericonlink';
    print('Weather icon link : $weathericonlink');

    return weathericonlink;
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    //getCurrentWeatherIcon();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
      child: Container(
        child: Padding(
          padding: const EdgeInsets.all(32.0),
          child: Column(
            children: <Widget>[
              Text('Hello'),
              Image(
                image: AssetImage('${getCurrentWeatherIcon()}'),
              ),
              Expanded(
                child: Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: AssetImage('assets/weathericons/day/113.png'),
                      fit: BoxFit.cover,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    ));
  }
}
like image 808
MKapp Avatar asked Jan 29 '26 08:01

MKapp


1 Answers

You should do some reading on what a Future is and how to handle them.

getData returns a Future, not the map that you think it does. To obtain the map from the future, you have to handle the future with either .then or async-await.

With await:

Future<String> getCurrentWeatherIcon() async {
  var weatherdata = await getData();

  String weathericonlink = weatherdata['current']['condition']['icon'];
  weathericonlink = weathericonlink.substring(35, weathericonlink.length);
  weathericonlink = 'assets/weathericons/$weathericonlink';
  print('Weather icon link : $weathericonlink');
   
  return weathericonlink;
}

or .then:

Future<String> getCurrentWeatherIcon() {
  return getData().then((weatherdata) {
    String weathericonlink = weatherdata['current']['condition']['icon'];
    weathericonlink = weathericonlink.substring(35, weathericonlink.length);
    weathericonlink = 'assets/weathericons/$weathericonlink';
    print('Weather icon link : $weathericonlink');
    return weathericonlink;
  });
}

Now that your getCurrentWeatherIcon function is also a future, you have to use a FutureBuilder to show the data.

Future weatherIcon;

@override
void initState() {
  super.initState();
  weatherIcon = getCurrentWeatherIcon();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Container(
        child: Padding(
          padding: const EdgeInsets.all(32.0),
          child: Column(
            children: <Widget>[
              Text('Hello'),
              FutureBuilder(
                future: weatherIcon,
                builder: (context, snapshot) {
                  if(!snapshot.hasData) {
                    return CircularProgressIndicator();
                  }
                  return Image(
                    image: AssetImage(snapshot.data),
                  );
                }
              ),
              Expanded(
                child: Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: AssetImage('assets/weathericons/day/113.png'),
                      fit: BoxFit.cover,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    )
  );
}
like image 172
Not A Bot Avatar answered Feb 01 '26 01:02

Not A Bot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!