I'm making weather forecast app with api. It has search bar on top and for now it looks like this:
It works but I'm getting this exception
main.dart
WeatherAPI client = WeatherAPI();
Weather? data = Weather();
String city = "Paris";
void getData() async {
final response = await client.getCurrentWeather(city);
setState(() {
data = response;
});
}
@override
Widget build(BuildContext context) {
getData();
return MaterialApp(
theme: ThemeData(fontFamily: 'Poppins'),
debugShowCheckedModeBanner: false,
home: Container (
decoration: BoxDecoration(
gradient: LinearGradient(begin: Alignment.topRight, end: Alignment.bottomLeft,
colors: [Color.fromRGBO(61, 43, 65, 1.0), Color.fromRGBO(39, 35, 52, 1.0)])
),
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.transparent,
appBar: AppBar(
title: title,
elevation: 0,
backgroundColor: Colors.transparent,
actions: [
IconButton(onPressed: (){
setState(() {
if(this.searchIcon.icon == Icons.search){
this.searchIcon = Icon(Icons.cancel);
this.title = TextField(
style: TextStyle(color: LIGHT_TEXT, fontSize: 15),
decoration: InputDecoration(border: InputBorder.none, hintText: "Search location",hintStyle: TextStyle(color: Colors.white30)),
textInputAction: TextInputAction.go,
controller: searchValue,
onSubmitted: (value) {
city = value;
this.title = Text("Weather Forecast");
this.searchIcon = Icon(Icons.search);
this.searchValue.text = "";
},
);
} else {
this.searchIcon = Icon(Icons.search);
this.title = Text("Weather Forecast");
}
});
}, icon: searchIcon,
)],
),
body: Column(
children: [
if(data != null)
Container(
height: 40,
),
currentWeather("${data!.city}", "${data!.temp}", "${data!.region}", "${data!.date}", "${data!.imgUrl}"),
Container(
height: 80,
child: Divider(color: LIGHT_TEXT_2, indent: 40, endIndent: 40,)
),
additionalWeather("${data!.feelsLike}", "${data!.wind}", "${data!.humidity}"),
])
)
)
);
}
Weather model:
class Weather {
String? city;
String? region;
double? temp;
double? wind;
int? humidity;
double? feelsLike;
double? gust;
String? date;
int? isDay;
String? imgUrl;
Weather({this.city, this.region, this.temp, this.wind, this.feelsLike, this.gust, this.humidity, this.date, this.isDay, this.imgUrl});
Weather.fromJSON(Map<String, dynamic> json){
city = json['location']['name'];
region = json['location']['region'];
temp = json['current']['temp_c'];
wind = json['current']['wind_kph'];
humidity = json['current']['humidity'];
feelsLike = json['current']['feelslike_c'];
gust = json['current']['gust_kph'];
date = json['location']['localtime'];
date = date!.substring(11);
isDay = json['current']['is_day'];
imgUrl = json['current']['condition']['icon'];
}
}
Weather api:
class WeatherAPI {
Future<Weather> getCurrentWeather(String? city) async {
var url = Uri.parse("http://api.weatherapi.com/v1/current.json?key=&q=$city&aqi=no");
var response = await http.get(url);
//print(response.statusCode);
var body = jsonDecode(response.body);
return Weather.fromJSON(body);
}
}
This is my code simplified. First I made this with Future builder but that way I failed to update the page when i search for another city. After that I managed to make the application work, but I can't fix this error. The first exception does not appear if I call getdata() in initstate() but in that case I am not able to search for the other city. Maybe this is not the right way to do this, I'm new to flutter. Any advice is welcome.
NetworkImage
widget but that doesn't exist in your code snippets. Just guessing but I image thatimgUrl
is null in your model and you are creating a string using this value which is causing the error.https:null
. So you might want to wrap the creating of the image with a null check to make sure that you have a url to getif(imgUrl != null)
but it doesnt work. it looks like this linkpicture.com/q/imgurl.jpg