I'm developing a weather app using an API from OpenWeatherMap. Every time I try to run my code, the error late initialization pops up. I've tried adding the null safety check(!) in place of late but it's still the same. Any idea where I could have gone wrong? Any help would be deeply appreciated. A sample code for solving the error would help a lot. Thanks!!
The error I'm getting in the console:
Performing hot restart... 1,492ms Restarted application in 1,501ms. ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ The following LateError was thrown building: LateInitializationError: Field 'weatherInfo' has not been initialized.
When the exception was thrown, this was the stack:
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49 throw
packages/finalproject/LastProject/LastProject_Screen.dart 13:44 get weatherInfo
packages/finalproject/LastProject/LastProject_Screen.dart 10:56 mainBodyWidget
packages/finalproject/LastProject/LastProject_Screen.dart 10:56
packages/flutter/src/widgets/sliver.dart 456:22 build
packages/flutter/src/widgets/sliver.dart 1214:28 [_build]
packages/flutter/src/widgets/sliver.dart 1227:55
packages/flutter/src/widgets/framework.dart 2573:19 buildScope
packages/flutter/src/widgets/sliver.dart 1220:5 createChild
packages/flutter/src/rendering/sliver_multi_box_adaptor.dart 349:23
packages/flutter/src/scheduler/binding.dart 1080:9 handleDrawFrame
packages/flutter/src/scheduler/binding.dart 863:7
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19 internalCallback
Note: This is just a part of the errors in the console because there are many.
The Code for UI:
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'LastProject_model.dart';
class LastProjectScreen extends StatefulWidget {
const LastProjectScreen({Key? key}) : super(key: key);
@override
_LastProjectScreenState createState() => _LastProjectScreenState();
}
class _LastProjectScreenState extends State<LastProjectScreen> {
//initializing model class object
late WeatherInfo weatherInfo;
TextEditingController _textEditingController = TextEditingController();
//overriding initstate to parse the data and display it on the screen
@override
void initState() {
super.initState();
}
//data parsing function to call the data from the json file
getData() async {
http.Response jsondata = await http.get(Uri.parse(
'https://api.openweathermap.org/data/2.5/forecast/daily?q=${_textEditingController.text}&units=metric&cnt=7&appid=3c044b7295d2df14f8bee74c19d4b96f'));
print(jsondata.body);
weatherInfo = WeatherInfo.fromJson(json.decode(jsondata.body));
return weatherInfo;
}
//first row of the screen
Widget uirow1(WeatherInfo weatherInfo) {
return Container(
padding: EdgeInsets.all(5),
margin: EdgeInsets.only(left: 20, right: 20, top: 20),
decoration: BoxDecoration(
// color: Colors.white,
gradient: LinearGradient(
colors: [Colors.blue.shade200, Colors.blue.shade50]),
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3),
)
]),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'name',
// weatherInfo.city.name,
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w700),
),
SizedBox(height: 5),
Text('temp °F',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black)),
SizedBox(height: 5),
Text('description',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Colors.black))
],
),
Icon(
Icons.cloud,
color: Colors.pink[400],
size: 100,
),
],
),
);
}
//second row of the screen
Widget uirow2() {
return Container(
padding: EdgeInsets.all(5),
margin: EdgeInsets.all(20),
decoration: BoxDecoration(
// color: Colors.white,
gradient: LinearGradient(
colors: [Colors.blue.shade200, Colors.blue.shade50]),
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3),
)
]),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('windSpeed',
style: TextStyle(
fontSize: 15,
)),
// SizedBox(width: 3),
Text('humidity',
style: TextStyle(
fontSize: 15,
)),
// SizedBox(width: 5),
Text('°F',
style: TextStyle(
fontSize: 15,
)),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(Icons.air_outlined, color: Colors.grey[600], size: 25),
// const SizedBox(width: 5),
Icon(Icons.whatshot_rounded, color: Colors.grey[600], size: 25),
// const SizedBox(width: 5),
Icon(Icons.air_outlined, color: Colors.grey[600], size: 25)
],
),
],
),
);
}
//main body widget of the screen
Widget mainBodyWidget(BuildContext context) {
return
// ListView(scrollDirection: Axis.vertical, children: [
Container(
padding: EdgeInsets.all(15),
decoration: const BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSZCv1LyQUyAJQE21-uNUMx3S8ZgK2U9S--1wQB59QaTFHBp2VqxGTAen5FRA7m5h-E4OU&usqp=CAU'),
fit: BoxFit.fill)),
child: Column(
children: [
searchwidget(),
const SizedBox(height: 15),
uirow1(weatherInfo),
const SizedBox(height: 15),
uirow2(),
const SizedBox(height: 15),
uirow3()
],
),
);
}
//third row of the screen
Widget uirow3() {
return Container(
padding: EdgeInsets.all(15),
margin: EdgeInsets.only(left: 20, right: 20),
height: 180,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue.shade200, Colors.blue.shade50]),
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3),
)
]),
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return Container(
child: uirow3data(),
);
},
separatorBuilder: (BuildContext context, int index) {
return SizedBox(width: 20);
},
itemCount: 7
// weatherInfo.weatherListInfo.length,
));
}
//data for the third row of the screen
Widget uirow3data() {
return Column(
children: [
Center(
child: Text('Saturday',
style: TextStyle(
fontWeight: FontWeight.bold,
))),
SizedBox(height: 5),
Icon(
Icons.cloud,
color: Colors.pink[400],
size: 50,
),
SizedBox(height: 4),
Text('High: 71°F'),
SizedBox(height: 3),
Text('Low: 71°F'),
SizedBox(height: 3),
Text('Hum: 40%'),
SizedBox(height: 3),
Text('Win: 4 mi/h')
],
);
}
//search textfiled widget
Widget searchwidget() {
return Container(
margin: EdgeInsets.only(left: 20, right: 20, top: 10),
child: Center(
child: TextField(
controller: _textEditingController,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
gapPadding: 3.0,
borderSide: const BorderSide(color: Colors.grey, width: 2.0),
borderRadius: BorderRadius.circular(11)),
hintText: 'Search',
hintStyle: const TextStyle(color: Colors.grey),
prefixIcon: const Icon(
Icons.search_sharp,
color: Colors.grey,
),
suffixIcon: InkWell(
child: const Icon(Icons.navigate_next, color: Colors.grey),
onTap: () => getData(),
)),
),
),
);
}
//main container widget
Widget mainContainerWidget(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: getData(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(child: Text("Couldn't load the data"));
}
if (snapshot.hasData) {
return Text("Data is being processed");
}
if (snapshot.data == null) {
return ListView.builder(
scrollDirection: Axis.vertical,
itemCount: 1,
shrinkWrap: true,
itemBuilder: (context, index) {
return Column(
children: [mainBodyWidget(context)],
);
});
}
return CircularProgressIndicator();
}));
}
//Main build function
@override
Widget build(BuildContext context) {
return mainContainerWidget(context);
}
}
The Code for Model class:
class WeatherInfo {
late CityInfo city;
late String cod;
late double message;
late int cnt;
late List<WeatherListInfo> weatherListInfo;
WeatherInfo(
this.city, this.cod, this.message, this.cnt, this.weatherListInfo);
factory WeatherInfo.fromJson(Map<String, dynamic> json) {
return WeatherInfo(
CityInfo.fromJson(json["city"]),
json["cod"],
json["message"],
json["cnt"],
(json["list"] as List).map((e) => WeatherListInfo.fromJson(e)).toList());
}
}
class CityInfo {
late String id;
late String name;
late String country;
late String population;
late String timezone;
CityInfo(this.id, this.name, this.country, this.population, this.timezone);
factory CityInfo.fromJson(Map<String, dynamic> json) {
return CityInfo(json["id"].toString(), json["name"], json["country"],
json["population"].toString(), json["timezone"].toString());
}
}
class WeatherListInfo {
late String dt;
late String sunrise;
late String sunset;
late TemperatureListInfo temperatureListInfo;
late String pressure;
late String humidity;
late List<WeatherDetailInfo> weatherDetailInfo;
late FeelsLikeListInfo feelsLikeInfo;
late String speed;
late String deg;
late String gust;
late String clouds;
late String pop;
late String rain;
WeatherListInfo(
this.dt,
this.sunrise,
this.sunset,
this.temperatureListInfo,
this.pressure,
this.humidity,
this.weatherDetailInfo,
this.feelsLikeInfo,
this.speed,
this.deg,
this.gust,
this.clouds,
this.pop,
this.rain,
);
factory WeatherListInfo.fromJson(Map<String, dynamic> json) {
return WeatherListInfo(
json["dt"].toString(),
json["sunrise"].toString(),
json["sunset"].toString(),
TemperatureListInfo.fromJson(json["temp"]),
json["pressure"].toString(),
json["humidity"].toString(),
(json["weather"] as List).map((e) => WeatherDetailInfo.fromJson(e)).toList(),
FeelsLikeListInfo.fromJson(json["feels_like"]),
json["speed"].toString(),
json["deg"].toString(),
json["gust"].toString(),
json["clouds"].toString(),
json["pop"].toString(),
json["rain"].toString(),
);
}
}
class TemperatureListInfo {
late String day;
late String min;
late String max;
late String night;
late String eve;
late String morn;
TemperatureListInfo(
this.day, this.night, this.eve, this.morn, this.min, this.max);
factory TemperatureListInfo.fromJson(Map<String, dynamic> json) {
return TemperatureListInfo(
json["day"].toString(),
json["night"].toString(),
json["eve"].toString(),
json["morn"].toString(),
json["min"].toString(),
json["max"].toString(),
);
}
}
class FeelsLikeListInfo {
late String day;
late String night;
late String eve;
late String morn;
FeelsLikeListInfo(this.day, this.night, this.eve, this.morn);
factory FeelsLikeListInfo.fromJson(Map<String, dynamic> json) {
return FeelsLikeListInfo(
json["day"].toString(),
json["night"].toString(),
json["eve"].toString(),
json["morn"].toString(),
);
}
}
class WeatherDetailInfo {
late String id;
late String main;
late String description;
late String icon;
WeatherDetailInfo(this.id, this.main, this.description, this.icon);
factory WeatherDetailInfo.fromJson(Map<String, dynamic> json) {
return WeatherDetailInfo(
json["id"].toString(),
json["main"],
json["description"],
json["icon"],
);
}
}
CodePudding user response:
The error message says it, you didn't initialize weatherInfo
. When you mark a variable as late
you must initialize it later, but in your case, you only initialize it when you call getData()
, so ui complains because it uses a variable that is not yet initialized. You have to options here,
first: you call getData
in initState
, so the variable will be initialized.
or, second: you remove the late
keyword and make the object nullable, but now you'll have to add null checks all over the code.
CodePudding user response:
In your main.dart add .
void main()async{
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}