Flutter - Open weather map : how to get 5 day forecast?

Viewed 18

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

0 Answers
Related