Learning to use Bloc and API together. I have been able to get current day weather details. However, what I'm trying to do is get todays weather details and a forecast for 5 days from today and show them on the UI.
I need help doing this.
home_bloc.dart:
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:hava/services/weatherService.dart';
part 'home_event.dart';
part 'home_state.dart';
class HomeBloc extends Bloc<HomeEvent, HomeState> {
final GetWeatherService _getWeatherService;
HomeBloc(this._getWeatherService) : super(HomeLoadingState()) {
on<LoadApiEvent>((event, emit) async {
// TODO: implement event handler
emit(HomeLoadingState());
final activity = await _getWeatherService.getWeather();
emit(HomeLoadedState(
activity.city.name.toString(),
activity.list[0].main.temp.toInt(),
activity.list[0].weather[0].main.toString(),
activity.city.sunrise,
activity.city.sunset
));
});
}
}
home_state.dart
part of 'home_bloc.dart';
abstract class HomeState extends Equatable {
const HomeState();
}
class HomeLoadingState extends HomeState {
@override
List<Object> get props => [];
}
class HomeLoadedState extends HomeState {
final dynamic city;
final dynamic temp;
final dynamic weather;
final dynamic sunRise;
final dynamic sunSet;
const HomeLoadedState(
this.city,
this.weather,
this.temp,
this.sunRise,
this.sunSet,
);
@override
List<Object?> get props => [city, temp, weather, sunRise, sunSet];
}
Weather Classes:
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:hava/services/openWeatherMapApi.dart';
import 'package:http/http.dart' as http;
import 'package:geolocator/geolocator.dart';
// To parse this JSON data, do
//
// final getWeatherDetails = getWeatherDetailsFromJson(jsonString);
GetWeatherDetails getWeatherDetailsFromJson(String str) =>
GetWeatherDetails.fromJson(json.decode(str));
String getWeatherDetailsToJson(GetWeatherDetails data) =>
json.encode(data.toJson());
class GetWeatherDetails {
GetWeatherDetails({
required this.cod,
required this.message,
required this.cnt,
required this.list,
required this.city,
});
String cod;
int message;
int cnt;
List<ListElement> list;
City city;
factory GetWeatherDetails.fromJson(Map<String, dynamic> json) =>
GetWeatherDetails(
cod: json["cod"],
message: json["message"],
cnt: json["cnt"],
list: List<ListElement>.from(
json["list"].map((x) => ListElement.fromJson(x))),
city: City.fromJson(json["city"]),
);
Map<String, dynamic> toJson() => {
"cod": cod,
"message": message,
"cnt": cnt,
"list": List<dynamic>.from(list.map((x) => x.toJson())),
"city": city.toString(),
};
}
class City {
City({
required this.id,
required this.name,
required this.coord,
required this.country,
required this.population,
required this.timezone,
required this.sunrise,
required this.sunset,
});
int id;
String name;
Coord coord;
String country;
int population;
int timezone;
int sunrise;
int sunset;
factory City.fromJson(Map<String, dynamic> json) => City(
id: json["id"],
name: json["name"],
coord: Coord.fromJson(json["coord"]),
country: json["country"],
population: json["population"],
timezone: json["timezone"],
sunrise: json["sunrise"],
sunset: json["sunset"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"coord": coord.toJson(),
"country": country,
"population": population,
"timezone": timezone,
"sunrise": sunrise,
"sunset": sunset,
};
}
class Coord {
Coord({
required this.lat,
required this.lon,
});
double lat;
double lon;
factory Coord.fromJson(Map<String, dynamic> json) => Coord(
lat: json["lat"].toDouble(),
lon: json["lon"].toDouble(),
);
Map<String, dynamic> toJson() => {
"lat": lat,
"lon": lon,
};
}
class ListElement {
ListElement({
required this.dt,
required this.main,
required this.weather,
required this.sys,
required this.dtTxt,
});
int dt;
Main main;
List<Weather> weather;
Sys sys;
DateTime dtTxt;
factory ListElement.fromJson(Map<String, dynamic> json) => ListElement(
dt: json["dt"],
main: Main.fromJson(json["main"]),
weather:
List<Weather>.from(json["weather"].map((x) => Weather.fromJson(x))),
sys: Sys.fromJson(json["sys"]),
dtTxt: DateTime.parse(json["dt_txt"]),
);
Map<String, dynamic> toJson() => {
"dt": dt,
"main": main.toJson(),
"weather": List<dynamic>.from(weather.map((x) => x.toJson())),
"sys": sys.toJson(),
"dt_txt": dtTxt.toIso8601String(),
};
}
class Main {
Main({
required this.temp,
required this.feelsLike,
required this.tempMin,
required this.tempMax,
});
double temp;
double feelsLike;
double tempMin;
double tempMax;
factory Main.fromJson(Map<String, dynamic> json) => Main(
temp: json["temp"].toDouble(),
feelsLike: json["feels_like"].toDouble(),
tempMin: json["temp_min"].toDouble(),
tempMax: json["temp_max"].toDouble(),
);
Map<String, dynamic> toJson() => {
"temp": temp,
"feels_like": feelsLike,
"temp_min": tempMin,
"temp_max": tempMax,
};
}
class Sys {
Sys({
required this.pod,
});
String pod;
factory Sys.fromJson(Map<String, dynamic> json) => Sys(
pod: json["pod"],
);
Map<String, dynamic> toJson() => {
"pod": pod,
};
}
class Weather {
Weather({
required this.id,
required this.main,
required this.description,
required this.icon,
});
int id;
String main;
String description;
String icon;
factory Weather.fromJson(Map<String, dynamic> json) => Weather(
id: json["id"],
main: json["main"],
description: json["description"],
icon: json["icon"],
);
Map<String, dynamic> toJson() => {
"id": id,
"main": main,
"description": description,
"icon": icon,
};
}
class GetWeatherService {
late LocationPermission checkPermission;
late LocationPermission requestPermission;
List coordinatesList = [];
late dynamic latitude;
late dynamic longitude;
//CHECK AND GET LOCATION PERMISSION
Future checkAndGetLocationPermissions() async {
// Check if gps is enabled
bool servicestatus = await Geolocator.isLocationServiceEnabled();
await Geolocator.requestPermission();
await Geolocator.checkPermission();
if (servicestatus) {
if (kDebugMode) {
print("GPS service is enabled");
}
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
latitude = position.latitude;
print(latitude);
longitude = position.longitude;
print(longitude);
coordinatesList.add(latitude);
coordinatesList.add(longitude);
if (kDebugMode) {
print(coordinatesList);
}
return coordinatesList;
} else {
if (kDebugMode) {
print("GPS service is disabled.");
}
// // Check for and request location permission
// permission = await Geolocator.checkPermission();
// if (permission == LocationPermission.denied) {
// permission = await Geolocator.requestPermission();
// if (permission == LocationPermission.denied) {
// if (kDebugMode) {
// print('Location permissions are denied');
// }
// } else if (permission == LocationPermission.deniedForever) {
// if (kDebugMode) {
// print("Location permissions are permanently denied");
// }
// } else {
// if (kDebugMode) {
// print("GPS Location service is granted");
// }
// }
// } else {
// if (kDebugMode) {
// print("GPS Location permission granted.");
// }
// }
}
// final response = await http.get(Uri.parse(
// "api.openweathermap.org/data/2.5/forecast?lat=${$position.lattude}&lon=$longitude&appid=$openWeatherMapApiKey"));
// final weatherDetails = getWeatherDetailsFromJson(response.body);
// return weatherDetails;
}
Future<GetWeatherDetails> getWeather() async {
dynamic latLong = await checkAndGetLocationPermissions() as List;
// print(latLong.runtimeType);
print("latLong, $latLong");
double latitude = latLong[0];
double longitude = latLong[1];
final response = await http.get(Uri.parse(
"http://api.openweathermap.org/data/2.5/forecast?lat=$latitude&lon=$longitude&units=metric&appid=$openWeatherMapApiKey"));
final weatherDetails = getWeatherDetailsFromJson(response.body.toString());
print(response);
return weatherDetails;
}
// Future<String> convertDateToDay() {
// return Null;
// }
}
Json Response:
{
"cod": "200",
"message": 0,
"cnt": 40,
"list": [
{
"dt": 1663880400,
"main": {
"temp": 295.86,
"feels_like": 296.33,
"temp_min": 295.86,
"temp_max": 295.86,
"pressure": 1013,
"sea_level": 1013,
"grnd_level": 950,
"humidity": 82,
"temp_kf": 0
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04n"
}
],
"clouds": {
"all": 71
},
"wind": {
"speed": 0.77,
"deg": 153,
"gust": 0.82
},
"visibility": 10000,
"pop": 0.04,
"sys": {
"pod": "n"
},
"dt_txt": "2022-09-22 21:00:00"
},
{
"dt": 1663880400,
"main": {
"temp": 295.86,
"feels_like": 296.33,
"temp_min": 295.86,
"temp_max": 295.86,
"pressure": 1013,
"sea_level": 1013,
"grnd_level": 950,
"humidity": 82,
"temp_kf": 0
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04n"
}
],
"clouds": {
"all": 71
},
"wind": {
"speed": 0.77,
"deg": 153,
"gust": 0.82
},
"visibility": 10000,
"pop": 0.04,
"sys": {
"pod": "n"
},
"dt_txt": "2022-09-23 21:00:00"
}
],
"city": {
"id": 2351027,
"name": "Akko",
"coord": {
"lat": 10.34,
"lon": 10.99
},
"country": "NG",
"population": 6129,
"timezone": 3600,
"sunrise": 1663391140,
"sunset": 1663434946
}
}
NOTE: I have shorted the Json response to just 2 days