Home > Blockchain >  Flutter: How to access different properties from different classes?
Flutter: How to access different properties from different classes?

Time:09-18

I'm building a weather app so I can learn working with API's and Bloc together. So far so good. However I have one problem, how can I access different properties from different classes?

This is my code with the 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;
  String 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"]).toString(),
      );

  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.");
      }

    }

    // 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&appid=$openWeatherMapApiKey"));
    final weatherDetails = getWeatherDetailsFromJson(response.body.toString());

    return weatherDetails;
  }
}

With the code above I am only able to acces properties from GetWeatherDetails such as 'city'.

I would like to be able to acces other propertes from other classes such as the ones in Classes, Main, City and List Element. How can I achieve this?

I am calling this method getWeather like 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();
      print(activity.city);
      emit(HomeLoadedState(activity.city));
    });
  }
}

This is the 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
    },
    "weather": [
      {
      "id": 803,
      "main": "Clouds",
      "description": "broken clouds",
      "icon": "04n"
      }
    ],
    "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
      },
      "weather": [
        {
        "id": 803,
        "main": "Clouds",
        "description": "broken clouds",
        "icon": "04n"
        }
      ],
      "dt_txt": "2022-09-22 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
  }
}

I have shortened the above json response to show weather details of 2 days only, but in the actual response it show weather details of 5 days.

The classes were generated in "quicktype" by pasting the json response.

Thank you for any help!

Edit 1: Code above reformatted.

Edit 2:Added Json response code above. I have shortened the above json response to show weather details of 2 days only, but in the actual response it show weather details of 5 days.

The classes were generated in "quicktype" by pasting the json response.

CodePudding user response:

The problem is you are assigning string type to "city" but "city" is City type(which is an object) consist of other attributes.

change this:

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; //here you assigned string but should be City type

  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"]), //here also you are changing it to 
    string
     );

    Map<String, dynamic> toJson() => {
    "cod": cod,
    "message": message,
    "cnt": cnt,
    "list": List<dynamic>.from(list.map((x) => x.toJson())),
    "city": city,  //here also you are changing it to string
  };
 }

  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,
    });

Now you can access the other property of City class

   HomeBloc(this._getWeatherService) : super(HomeLoadingState()) {
      on<LoadApiEvent>((event, emit) async {
       // TODO: implement event handler
        emit(HomeLoadingState());
        final activity = await _getWeatherService.getWeather();
        print(activity.city.coord.lat);
        print(activity.city.name);
        // here you can access all

        print(activity.city.list[0].main.temp);// you can loop through 
         the list and get the specific value. I just assigned the 
         first index

     });
   }

CodePudding user response:

Use this response 

    class WeatherOne {
      String? cod;
      int? message;
      int? cnt;
      List<WeatherList>? list;
      City? city;
    
      WeatherOne({this.cod, this.message, this.cnt, this.list, this.city});
    
      WeatherOne.fromJson(Map<String, dynamic> json) {
        cod = json['cod'];
        message = json['message'];
        cnt = json['cnt'];
        if (json['list'] != null) {
          list = <WeatherList>[];
          json['list'].forEach((v) {
            list!.add(new WeatherList.fromJson(v));
          });
        }
        city = json['city'] != null ? new City.fromJson(json['city']) : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['cod'] = this.cod;
        data['message'] = this.message;
        data['cnt'] = this.cnt;
        if (this.list != null) {
          data['list'] = this.list!.map((v) => v.toJson()).toList();
        }
        if (this.city != null) {
          data['city'] = this.city!.toJson();
        }
        return data;
      }
    }
    
    class WeatherList {
      int? dt;
      Main? main;
      List<Weather>? weather;
      String? dtTxt;
    
      WeatherList({this.dt, this.main, this.weather, this.dtTxt});
    
      WeatherList.fromJson(Map<String, dynamic> json) {
        dt = json['dt'];
        main = json['main'] != null ? new Main.fromJson(json['main']) : null;
        if (json['weather'] != null) {
          weather = <Weather>[];
          json['weather'].forEach((v) {
            weather!.add(new Weather.fromJson(v));
          });
        }
        dtTxt = json['dt_txt'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['dt'] = this.dt;
        if (this.main != null) {
          data['main'] = this.main!.toJson();
        }
        if (this.weather != null) {
          data['weather'] = this.weather!.map((v) => v.toJson()).toList();
        }
        data['dt_txt'] = this.dtTxt;
        return data;
      }
    }
    
    class Main {
      double? temp;
      double? feelsLike;
      double? tempMin;
      double? tempMax;
    
      Main({this.temp, this.feelsLike, this.tempMin, this.tempMax});
    
      Main.fromJson(Map<String, dynamic> json) {
        temp = json['temp'];
        feelsLike = json['feels_like'];
        tempMin = json['temp_min'];
        tempMax = json['temp_max'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['temp'] = this.temp;
        data['feels_like'] = this.feelsLike;
        data['temp_min'] = this.tempMin;
        data['temp_max'] = this.tempMax;
        return data;
      }
    }
    
    class Weather {
      int? id;
      String? main;
      String? description;
      String? icon;
    
      Weather({this.id, this.main, this.description, this.icon});
    
      Weather.fromJson(Map<String, dynamic> json) {
        id = json['id'];
        main = json['main'];
        description = json['description'];
        icon = json['icon'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['id'] = this.id;
        data['main'] = this.main;
        data['description'] = this.description;
        data['icon'] = this.icon;
        return data;
      }
    }
    
    class City {
      int? id;
      String? name;
      Coord? coord;
      String? country;
      int? population;
      int? timezone;
      int? sunrise;
      int? sunset;
    
      City(
          {this.id,
            this.name,
            this.coord,
            this.country,
            this.population,
            this.timezone,
            this.sunrise,
            this.sunset});
    
      City.fromJson(Map<String, dynamic> json) {
        id = json['id'];
        name = json['name'];
        coord = json['coord'] != null ? new Coord.fromJson(json['coord']) : null;
        country = json['country'];
        population = json['population'];
        timezone = json['timezone'];
        sunrise = json['sunrise'];
        sunset = json['sunset'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['id'] = this.id;
        data['name'] = this.name;
        if (this.coord != null) {
          data['coord'] = this.coord!.toJson();
        }
        data['country'] = this.country;
        data['population'] = this.population;
        data['timezone'] = this.timezone;
        data['sunrise'] = this.sunrise;
        data['sunset'] = this.sunset;
        return data;
      }
    }
    
    class Coord {
      double? lat;
      double? lon;
    
      Coord({this.lat, this.lon});
    
      Coord.fromJson(Map<String, dynamic> json) {
        lat = json['lat'];
        lon = json['lon'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['lat'] = this.lat;
        data['lon'] = this.lon;
        return data;
      }
    }
  • Related