I'm trying to pass data to a flutter user interface from the open weather API. I think it has something to do with where I am initializing the city name variable as it gets rebuilt every time I refresh the app and just loads the original string instead of the city I put in the text field. How would I fix this code so I can pull the information from the API using the new city name.
import 'package:flutter/material.dart';
import 'package:weather_solo/logic/get_weather.dart';
//import 'logic/additional_information_info.dart';
import 'logic/weather_forecast_time.dart';
class WeatherHomePage extends StatefulWidget {
const WeatherHomePage({super.key});
@override
State<WeatherHomePage> createState() => _WeatherHomePageState();
}
class _WeatherHomePageState extends State<WeatherHomePage> {
TextEditingController cityNameController = TextEditingController();
GetWeather getWeather = GetWeather();
String cityName = 'Hamilton';
late Future<Map<String, dynamic>> weather = getWeather.getCurrentWeather(cityName);
// late int iconID = weather['list'][0];
//list[0].weather[0].id
@override
void initState() {
super.initState();
weather = getWeather.getCurrentWeather(cityName);
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('My Weather App',
style: TextStyle(
fontSize: 20,
),),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Card(
elevation: 10,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: cityNameController,
decoration: const InputDecoration(
hintText: 'Please Enter City Name Here',
border: OutlineInputBorder()
),
),
ElevatedButton(onPressed: () {
setState(() {
cityName = cityNameController.text;
cityNameController.clear();
getWeather.getCurrentWeather(cityName);
});
},
style: const ButtonStyle(
elevation: MaterialStatePropertyAll(10),
backgroundColor:
MaterialStatePropertyAll(Colors.red),
foregroundColor: MaterialStatePropertyAll(Colors.black),
),
child: const Text(
'Choose City'
),
),
],
),
),
),
// Flex for weather data, needs to be wrapped in a FutureBuilder as this is the section that will update
FutureBuilder(
future: weather,
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator.adaptive(),
);
}
if (snapshot.hasError) {
return Center(
child: Text(snapshot.error.toString()),
);
}
final data = snapshot.data!;
final currentWeatherData = data['list'][0];
final currentIcon = currentWeatherData['weather'][0]['id'];
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Card(
elevation: 10, //Main weather data card
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
const SizedBox(width: double.infinity,),
Text(cityName,
style: const TextStyle(
fontSize: 15,
),),
const SizedBox(height: 10,),
Text('Weather icon code $currentIcon Rain',
style: const TextStyle(
fontSize: 10
),),
const SizedBox(
height: 5,
),
const Icon(Icons.cloud,
size: 20,),
const SizedBox(height: 5,),
const Text('27 °C',
style: TextStyle(
fontSize: 20
),) //Hold down left alt and numpad 0176 for degree symbol
],
),
),
// Wetaher data time forecast
SizedBox(
height: 100,
child: ListView.builder(itemCount: 5,scrollDirection: Axis.horizontal,itemBuilder: (context ,index) {
return const WeatherForecastTime(time: '09.00', icon: Icons.sunny, desctription: 'Sunny',);
},
),
),
//Additional information
// const Row(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// children: [
// AdditionalInformationInfo(title: 'Humidity', icon: Icons.water_drop, stats: '4757',),
// AdditionalInformationInfo(title: 'Wind Speed', icon: Icons.air, stats: 'Fast',),
// AdditionalInformationInfo(title: 'Pressure', icon: Icons.umbrella, stats: '775',)
// ],
// ),
],
),
);
}
)
],
),
),
),
);
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'secrets.dart';
class GetWeather {
Future<Map<String, dynamic>> getCurrentWeather(String cityName) async {
try {
final result = await http.get(Uri.parse(
'http://api.openweathermap.org/data/2.5/forecast?q=$cityName&appid=$openWeatherAPIKey'));
final data = jsonDecode(result.body);
if (result.statusCode != 200) {
throw 'An unexpected error occured ${data['cod']}';
}
print(result.body);
return data;
} catch (e) {
throw e.toString();
}
}
Icon getWeatherIcon(int condition) {
switch (condition) {
case < 300:
return const Icon(Icons.thunderstorm);
case < 400:
return const Icon(Icons.water_drop);
case < 600:
return const Icon(Icons.umbrella);
case < 700:
return const Icon(Icons.snowing);
case < 800:
return const Icon(Icons.foggy);
case == 800:
return const Icon(Icons.sunny);
case <= 804:
return const Icon(Icons.cloud);
default:
return const Icon(Icons.question_mark);
}
}
}
This fixed it.