Home > Software engineering >  Expected a value of type 'String', but got one of the type 'Null'
Expected a value of type 'String', but got one of the type 'Null'

Time:12-28

import 'package:flutter/material.dart';
import 'widgets/main_widget.dart';

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

import 'dart:async';

import 'dart:convert';


Future<WeatherInfo> fetchWeather() async {

  final zipCode = "180007";

  final apiKey = "d415dc7d3cae2e2b8a722dca06eb9e88";

  final requestUrl =
      "http://api.openweathermap.org/data/2.5/weather?zip={zipCode},IN&units=imperial&appid={apiKey}";


  final response = await http.get(Uri.parse(requestUrl));

  return WeatherInfo.fromJson(jsonDecode(response.body));
}


class WeatherInfo {

  final String location;

  final double temp;

  final double tempMin;

  final double tempMax;

  final String weather;

  final int Humidity;

  final double windspeed;

  WeatherInfo(

      {required this.location,

      required this.temp,

      required this.tempMin,

      required this.tempMax,

      required this.weather,

      required this.Humidity,

      required this.windspeed});

  factory WeatherInfo.fromJson(Map<String, dynamic> json) {

    return WeatherInfo(

        location: json['name'],

        temp: json['main']['temp'],

        tempMin: json['main']['temp_min'],

        tempMax: json['main']['temp_max'],

        weather: json['weather']['description'],

        Humidity: json['main']['humidity'],

        windspeed: json['wind']['speed']);

  }
}

void main() => runApp(MaterialApp(title: "Weather App", home: MyApp()));


class MyApp extends StatefulWidget {

  @override

  State<StatefulWidget> createState() {

    return _MyApp();

  }
}

class _MyApp extends State<MyApp> {

  late Future<WeatherInfo> futureWeather;

  @override

  void initState() {

    super.initState();

    futureWeather = fetchWeather();
  }

  @override

  Widget build(BuildContext context) {

    return Scaffold(

        body: FutureBuilder<WeatherInfo>(

            future: futureWeather,

            builder: (context, Snapshot) {

              if (Snapshot.hasData) {

                return MainWidget(

                    location: Snapshot.data!.location,

                    temp: Snapshot.data!.temp,

                    tempMin: Snapshot.data!.tempMin,

                    tempMax: Snapshot.data!.tempMax,

                    weather: Snapshot.data!.weather,

                    Humidity: Snapshot.data!.Humidity,

                    windspeed: Snapshot.data!.windspeed);

              } else if (Snapshot.hasError) {

                return Center(

                  child: Text("${Snapshot.error}"),

                );
              }

              return CircularProgressIndicator();
            }));
  }
}

CodePudding user response:

I see two problems in your code:

  1. if you intend to imbed the apiKey and zipCode into requestUrl then you have to use $ before {apiKey} and {zipCode}.
  2. You are getting this error because of null-safety if I'm not mistaken, you can declare the WeatherInfo class attributes to handle null value by adding ? after the type specification (eg. String? or double?).

but I guess if you fixed the first issue then the second solution won't be necessary since I guess you are getting error response from the API which causes the variables to be null, so print the response you get to check and don't forget to handle the error response.

CodePudding user response:

you should make await while calling fetchweather()

void initState() {

    super.initState();
    fun();
}

void fun() async {
futureWeather = await fetchWeather();
setState(() {});
  }
}
  • Related