skip to Main Content

I am having this problem converting the following json to TodayWeather entity. How can I use the named constructor TodayHours?

I’ve been looking for a solution for this issue for a few days now, but I haven’t found much, please guide me.

enter image description here

JSON:

 {
    "days": [
        {
            "datetime": "2023-01-05",
            "datetimeEpoch": 1672864200,
            "tempmax": 8.8,
            "tempmin": 2.3,
            "temp": 5.3,
            "windspeed": 8.6,
            "winddir": 223.9,
            "visibility": 19.7,
            "sunrise": "06:43:43",
            "sunset": "16:30:24",
            "conditions": "Snow, Rain, Overcast",
            "hours": [
                {
                    "datetime": "00:00:00",
                    "datetimeEpoch": 1672864200,
                    "temp": 4.4,
                    "humidity": 27.65,
                    "windspeed": 6.5,
                    "winddir": 249.2,
                    "visibility": 24.1,
                    "conditions": "Partially cloudy"
                },
                {
                    "datetime": "01:00:00",
                    "datetimeEpoch": 1672864200,
                    "temp": 4.4,
                    "humidity": 27.65,
                    "windspeed": 6.5,
                    "winddir": 249.2,
                    "visibility": 24.1,
                    "conditions": "Partially cloudy"
                }
            ]
        }
    ]
}

And my TodayWeather entity is:

 class TodayWeather {
  final String datetime;
  final num dateEpoch;
  final String conditions;
  final num tempMax;
  final num tempMin;
  final num windDir;
  final num windSpeed;
  final String sunRise;
  final String sunSet;
  final num humidity;
  final num visibility;
  final List<TodayHourse> hours;

  TodayWeather.fromJson(Map<String, dynamic> json)
      : datetime = json['days'][0]['datetime'],
        dateEpoch = json['days'][0]['datetimeEpoch'],
        conditions = json['days'][0]['conditions'],
        tempMax = json['days'][0]['tempmax'],
        tempMin = json['days'][0]['tempmin'],
        windDir = json['days'][0]['winddir'],
        windSpeed = json['days'][0]['windspeed'],
        sunRise = json['days'][0]['sunrise'],
        sunSet = json['days'][0]['sunset'],
        humidity = json['days'][0]['humidity'],
        visibility = json['days'][0]['visibility'],
        hours = List<TodayHourse>.from(
            json['days'][0]['hours'].map((x) => x.toJson())).toList();
}

This is my TodayHours entity:

 class TodayHourse {
  final String datetime;
  final num dateEpoch;
  final String conditions;
  final num temp;
  final num windDir;
  final num windSpeed;
  final num humidity;
  final num visibility;

  Map<String, dynamic> toJson() => {
        'datetime': datetime,
        'datetimeEpoch': dateEpoch,
        'conditions': conditions,
        'temp': temp,
        'winddir': windDir,
        'windspeed': windSpeed,
        'humidity': humidity,
        'visibility': visibility
      };

  TodayHourse.fromJson(Map<String, dynamic> json)
      : datetime = json['days'][0]['datetime'],
        dateEpoch = json['days'][0]['datetimeEpoch'],
        conditions = json['days'][0]['conditions'],
        temp = json['days'][0]['temp'],
        windDir = json['days'][0]['winddir'],
        windSpeed = json['days'][0]['windspeed'],
        humidity = json['days'][0]['humidity'],
        visibility = json['days'][0]['visibility'];
}

This method is parsing Json to TodayWeather:

@override
  Future<TodayWeather> getTodayWeather() async {
    final response = await httpClient.get(
        '36.31559%2C59.56796/today?unitGroup=metric&key=Key&contentType=json');
    validResponse(response);
    return TodayWeather.fromJson(response.data);
  }

3

Answers


  1. First change your TodayHourse.fromJson to this:

    TodayHourse.fromJson(Map<String, dynamic> json)
          : datetime = json['datetime'],
            dateEpoch = json['datetimeEpoch'],
            conditions = json['conditions'],
            temp = json['temp'],
            windDir = json['winddir'],
            windSpeed = json['windspeed'],
            humidity = json['humidity'],
            visibility = json['visibility'];
    

    your hours is list of Map and you don’t need to use json['days'][0]. Then in your TodayWeather.fromJson, change hours to this:

    hours = (json['days'][0]['hours'] as List).map((x) => TodayHourse.fromJson(x)).toList();
    

    you are using wrong function instead of toJson, you need to call TodayHourse.fromJson(x).

    Login or Signup to reply.
  2. Try to use this model:

    class TodayWeather {
      TodayWeather({required this.days});
    
      final List<Day> days;
    
      factory TodayWeather.fromJson(Map<String, dynamic> json) => TodayWeather(
            days: List<Day>.from(json["days"].map((x) => Day.fromJson(x))),
          );
    }
    
    class Day {
      Day({
        required this.datetime,
        required this.datetimeEpoch,
        required this.tempmax,
        required this.tempmin,
        required this.temp,
        required this.windspeed,
        required this.winddir,
        required this.visibility,
        required this.sunrise,
        required this.sunset,
        required this.conditions,
        required this.hours,
      });
    
      final DateTime datetime;
      final int datetimeEpoch;
      final double tempmax, tempmin, temp, windspeed, winddir, visibility;
      final String sunrise, sunset, conditions;
      final List<Hour> hours;
    
      factory Day.fromJson(Map<String, dynamic> json) => Day(
            datetime: DateTime.parse(json["datetime"]),
            datetimeEpoch: json["datetimeEpoch"],
            tempmax: json["tempmax"].toDouble(),
            tempmin: json["tempmin"].toDouble(),
            temp: json["temp"].toDouble(),
            windspeed: json["windspeed"].toDouble(),
            winddir: json["winddir"].toDouble(),
            visibility: json["visibility"].toDouble(),
            sunrise: json["sunrise"],
            sunset: json["sunset"],
            conditions: json["conditions"],
            hours: List<Hour>.from(json["hours"].map((x) => Hour.fromJson(x))),
          );
    }
    
    class Hour {
      Hour({
        required this.datetime,
        required this.datetimeEpoch,
        required this.temp,
        required this.humidity,
        required this.windspeed,
        required this.winddir,
        required this.visibility,
        required this.conditions,
      });
    
      final int datetimeEpoch;
      final double temp, humidity, windspeed, winddir, visibility;
      final String datetime, conditions;
    
      factory Hour.fromJson(Map<String, dynamic> json) => Hour(
            datetime: json["datetime"],
            datetimeEpoch: json["datetimeEpoch"],
            temp: json["temp"].toDouble(),
            humidity: json["humidity"].toDouble(),
            windspeed: json["windspeed"].toDouble(),
            winddir: json["winddir"].toDouble(),
            visibility: json["visibility"].toDouble(),
            conditions: json["conditions"],
          );
    }
    
    Login or Signup to reply.
  3. First of all for more clear way to parse JSON arrays you can create helper method in your models, I call it Model.fromJsonList

     static List<WeatherDay> fromJsonList(dynamic jsonList) {
        if (jsonList == null || jsonList.isEmpty) return [];
        return (jsonList as List).map((e) => WeatherDay.fromJson(e)).toList();
      }
    

    So by this method you can parse array response very easy and clean for example:

      Future<WeatherDay> fetchTodayWeather() async {
        final response = await httpClient.get(
            '36.31559%2C59.56796/today?unitGroup=metric&key=Key&contentType=json');
        final List<WeatherDay> weatherDays = WeatherDay.fromJsonList(response.data["days"]);
        return weatherDays.first;
      }
    

    Totally we have:

    class WeatherDay {
      WeatherDay( {
        @required this.datetime,
        @required this.hours,
      });
    
      final String datetime;
      final List<WeatherHour> hours;
    
      factory WeatherDay.fromJson(Map<String, dynamic> json) {
        return WeatherDay(
          datetime: json['datetime'] as String,
          hours: WeatherHour.fromJsonList(json['hours']),
        );
      }
    
      static List<WeatherDay> fromJsonList(dynamic jsonList) {
        if (jsonList == null || jsonList.isEmpty) return [];
        return (jsonList as List).map((e) => WeatherDay.fromJson(e)).toList();
      }
    }
    
    class WeatherHour {
      WeatherHour( {
        @required this.dateEpoch,
        @required this.conditions,
      });
    
      final num dateEpoch;
      final String conditions;
    
      factory WeatherHour.fromJson(Map<String, dynamic> json) {
        return WeatherHour(
          dateEpoch: json['datetimeEpoch'] as num,
          conditions: json['conditions'] as String,
        );
      }
    
      static List<WeatherHour> fromJsonList(dynamic jsonList) {
        if (jsonList == null || jsonList.isEmpty) return [];
        return (jsonList as List).map((e) => WeatherHour.fromJson(e)).toList();
      }
    }
    

    Note: I didn’t parse all variable, do it by yourself.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search