Estoy aprendiendo flutter e intentando analizar un JSON como en este artículo, pero obteniendo este error.

lib / service / apiservice.dart: 11: 33: Error: No se puede asignar un valor de tipo 'Datos' a una variable de tipo 'Lista'. - 'Datos' es de 'paquete: gocorona / models / totals.dart' ('lib / models / totals.dart'). - 'Lista' es de 'dart: core'. Datos finales de la lista = dataFromJson (response.body);

lib / service / apiservice.dart

import 'package:http/http.dart' as http;
import 'package:gocorona/models/totals.dart';

class ApiServices {

  static const String url = 'https://api.rootnet.in/covid19-in/stats/latest';
static Future<List<Data>> getDataFromAPI() async {
    try {
      final response = await http.get(url);
      if (200 == response.statusCode) {
        final List<Data> data = dataFromJson(response.body);
        return data;
      } else {
        return List<Data>();
      }
    } catch (e) {
      return List<Data>();
    }
  }
}

lib / models / totals.dart

import 'dart:convert';

Data dataFromJson(String str) => Data.fromJson(json.decode(str));

String dataToJson(Data data) => json.encode(data.toJson());

class Data {
    bool success;
    DataClass data;
    DateTime lastRefreshed;
    DateTime lastOriginUpdate;

    Data({
        this.success,
        this.data,
        this.lastRefreshed,
        this.lastOriginUpdate,
    });

    factory Data.fromJson(Map<String, dynamic> json) => Data(
        success: json["success"],
        data: DataClass.fromJson(json["data"]),
        lastRefreshed: DateTime.parse(json["lastRefreshed"]),
        lastOriginUpdate: DateTime.parse(json["lastOriginUpdate"]),
    );

    Map<String, dynamic> toJson() => {
        "success": success,
        "data": data.toJson(),
        "lastRefreshed": lastRefreshed.toIso8601String(),
        "lastOriginUpdate": lastOriginUpdate.toIso8601String(),
    };
}

class DataClass {
    Summary summary;
    List<UnofficialSummary> unofficialSummary;
    List<Regional> regional;

    DataClass({
        this.summary,
        this.unofficialSummary,
        this.regional,
    });

    factory DataClass.fromJson(Map<String, dynamic> json) => DataClass(
        summary: Summary.fromJson(json["summary"]),
        unofficialSummary: List<UnofficialSummary>.from(json["unofficial-summary"].map((x) => UnofficialSummary.fromJson(x))),
        regional: List<Regional>.from(json["regional"].map((x) => Regional.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "summary": summary.toJson(),
        "unofficial-summary": List<dynamic>.from(unofficialSummary.map((x) => x.toJson())),
        "regional": List<dynamic>.from(regional.map((x) => x.toJson())),
    };
}

class Regional {
    String loc;
    int confirmedCasesIndian;
    int discharged;
    int deaths;
    int confirmedCasesForeign;
    int totalConfirmed;

    Regional({
        this.loc,
        this.confirmedCasesIndian,
        this.discharged,
        this.deaths,
        this.confirmedCasesForeign,
        this.totalConfirmed,
    });

    factory Regional.fromJson(Map<String, dynamic> json) => Regional(
        loc: json["loc"],
        confirmedCasesIndian: json["confirmedCasesIndian"],
        discharged: json["discharged"],
        deaths: json["deaths"],
        confirmedCasesForeign: json["confirmedCasesForeign"],
        totalConfirmed: json["totalConfirmed"],
    );

    Map<String, dynamic> toJson() => {
        "loc": loc,
        "confirmedCasesIndian": confirmedCasesIndian,
        "discharged": discharged,
        "deaths": deaths,
        "confirmedCasesForeign": confirmedCasesForeign,
        "totalConfirmed": totalConfirmed,
    };
}

class Summary {
    int total;
    int confirmedCasesIndian;
    int confirmedCasesForeign;
    int discharged;
    int deaths;
    int confirmedButLocationUnidentified;

    Summary({
        this.total,
        this.confirmedCasesIndian,
        this.confirmedCasesForeign,
        this.discharged,
        this.deaths,
        this.confirmedButLocationUnidentified,
    });

    factory Summary.fromJson(Map<String, dynamic> json) => Summary(
        total: json["total"],
        confirmedCasesIndian: json["confirmedCasesIndian"],
        confirmedCasesForeign: json["confirmedCasesForeign"],
        discharged: json["discharged"],
        deaths: json["deaths"],
        confirmedButLocationUnidentified: json["confirmedButLocationUnidentified"],
    );

    Map<String, dynamic> toJson() => {
        "total": total,
        "confirmedCasesIndian": confirmedCasesIndian,
        "confirmedCasesForeign": confirmedCasesForeign,
        "discharged": discharged,
        "deaths": deaths,
        "confirmedButLocationUnidentified": confirmedButLocationUnidentified,
    };
}

class UnofficialSummary {
    String source;
    int total;
    int recovered;
    int deaths;
    int active;

    UnofficialSummary({
        this.source,
        this.total,
        this.recovered,
        this.deaths,
        this.active,
    });

    factory UnofficialSummary.fromJson(Map<String, dynamic> json) => UnofficialSummary(
        source: json["source"],
        total: json["total"],
        recovered: json["recovered"],
        deaths: json["deaths"],
        active: json["active"],
    );

    Map<String, dynamic> toJson() => {
        "source": source,
        "total": total,
        "recovered": recovered,
        "deaths": deaths,
        "active": active,
    };
}

lib / Screens / states.dart

import 'package:flutter/material.dart';
import 'package:gocorona/models/totals.dart';
import 'package:gocorona/service/apiservice.dart';

class Statewise extends StatefulWidget {
  @override
  _StatewiseState createState() => _StatewiseState();
}

class _StatewiseState extends State<Statewise> {
  List<Data> _datafromApi;
  bool _isloading;

  @override
  void initState() {
    super.initState();

    _isloading = true;
    ApiServices.getDataFromAPI().then((data) {
      setState(() {
        _datafromApi = data;
        _isloading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_isloading) {
      return Container(
        child: Center(
          child: CircularProgressIndicator(),
        ),
      );
    } else {
      return Scaffold(
        body: ListView.builder(
            itemCount: _datafromApi == null ? 0 : _datafromApi.length,
            itemBuilder: (context, index) {
              Data datas = _datafromApi[index];
              print(datas?.toString() ?? "Empty");
              return ListTile(
                  title: Text(
                datas.data.regional[0].loc.toString(),
                style: TextStyle(color: Colors.black),
              ));
            }),
      );
    }
  }
}

Mensaje del compilador:

lib/service/apiservice.dart:11:33: Error: A value of type 'Data' can't be assigned to a variable of type 'List<Data>'.
 - 'Data' is from 'package:gocorona/models/totals.dart' ('lib/models/totals.dart').
 - 'List' is from 'dart:core'.
        final List<Data> data = dataFromJson(response.body);
                                ^

Doctora aleteo

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.17.0, on Microsoft Windows [Version 10.0.18362.778], locale en-IN)

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[√] Android Studio (version 3.6)
[√] VS Code (version 1.45.0)
[√] Connected device (1 available)

• No issues found!

0
zoldyck-kun21 10 may. 2020 a las 14:59

3 respuestas

La mejor respuesta

Esto sucedía porque solo devolvía datos del constructor e intentaba aceptarlos como una Lista.

Hice algunos cambios, espero que te ayude.

class ApiServices {
  static const String url = 'https://api.rootnet.in/covid19-in/stats/latest';
  static Future<Data> getDataFromAPI() async {
    try {
      final response = await http.get(url);
      if (200 == response.statusCode) {
        print(response.toString());

        final data = dataFromJson(response.body);

        //  print(data);
        return data;
      } else {
        return Data();
      }
    } catch (e) {
      return Data();
    }
  }
}

Data dataFromJson(String str) => Data.fromJson(json.decode(str));

String dataToJson(Data data) => json.encode(data.toJson());

class Data {
  bool success;
  DataClass data;
  DateTime lastRefreshed;
  DateTime lastOriginUpdate;

  Data({
    this.success,
    this.data,
    this.lastRefreshed,
    this.lastOriginUpdate,
  });

  factory Data.fromJson(Map<String, dynamic> json) => Data(
        success: json["success"],
        data: DataClass.fromJson(json["data"]),
        lastRefreshed: DateTime.parse(json["lastRefreshed"]),
        lastOriginUpdate: DateTime.parse(json["lastOriginUpdate"]),
      );

  Map<String, dynamic> toJson() => {
        "success": success,
        "data": data.toJson(),
        "lastRefreshed": lastRefreshed.toIso8601String(),
        "lastOriginUpdate": lastOriginUpdate.toIso8601String(),
      };
}

class DataClass {
  Summary summary;
  List<UnofficialSummary> unofficialSummary;
  List<Regional> regional;

  DataClass({
    this.summary,
    this.unofficialSummary,
    this.regional,
  });

  factory DataClass.fromJson(Map<String, dynamic> json) => DataClass(
        summary: Summary.fromJson(json["summary"]),
        unofficialSummary: List<UnofficialSummary>.from(
            json["unofficial-summary"]
                .map((x) => UnofficialSummary.fromJson(x))),
        regional: List<Regional>.from(
            json["regional"].map((x) => Regional.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "summary": summary.toJson(),
        "unofficial-summary":
            List<dynamic>.from(unofficialSummary.map((x) => x.toJson())),
        "regional": List<dynamic>.from(regional.map((x) => x.toJson())),
      };
}

class Regional {
  String loc;
  int confirmedCasesIndian;
  int discharged;
  int deaths;
  int confirmedCasesForeign;
  int totalConfirmed;

  Regional({
    this.loc,
    this.confirmedCasesIndian,
    this.discharged,
    this.deaths,
    this.confirmedCasesForeign,
    this.totalConfirmed,
  });

  factory Regional.fromJson(Map<String, dynamic> json) => Regional(
        loc: json["loc"],
        confirmedCasesIndian: json["confirmedCasesIndian"],
        discharged: json["discharged"],
        deaths: json["deaths"],
        confirmedCasesForeign: json["confirmedCasesForeign"],
        totalConfirmed: json["totalConfirmed"],
      );

  Map<String, dynamic> toJson() => {
        "loc": loc,
        "confirmedCasesIndian": confirmedCasesIndian,
        "discharged": discharged,
        "deaths": deaths,
        "confirmedCasesForeign": confirmedCasesForeign,
        "totalConfirmed": totalConfirmed,
      };
}

class Summary {
  int total;
  int confirmedCasesIndian;
  int confirmedCasesForeign;
  int discharged;
  int deaths;
  int confirmedButLocationUnidentified;

  Summary({
    this.total,
    this.confirmedCasesIndian,
    this.confirmedCasesForeign,
    this.discharged,
    this.deaths,
    this.confirmedButLocationUnidentified,
  });

  factory Summary.fromJson(Map<String, dynamic> json) => Summary(
        total: json["total"],
        confirmedCasesIndian: json["confirmedCasesIndian"],
        confirmedCasesForeign: json["confirmedCasesForeign"],
        discharged: json["discharged"],
        deaths: json["deaths"],
        confirmedButLocationUnidentified:
            json["confirmedButLocationUnidentified"],
      );

  Map<String, dynamic> toJson() => {
        "total": total,
        "confirmedCasesIndian": confirmedCasesIndian,
        "confirmedCasesForeign": confirmedCasesForeign,
        "discharged": discharged,
        "deaths": deaths,
        "confirmedButLocationUnidentified": confirmedButLocationUnidentified,
      };
}

class UnofficialSummary {
  String source;
  int total;
  int recovered;
  int deaths;
  int active;

  UnofficialSummary({
    this.source,
    this.total,
    this.recovered,
    this.deaths,
    this.active,
  });

  factory UnofficialSummary.fromJson(Map<String, dynamic> json) =>
      UnofficialSummary(
        source: json["source"],
        total: json["total"],
        recovered: json["recovered"],
        deaths: json["deaths"],
        active: json["active"],
      );

  Map<String, dynamic> toJson() => {
        "source": source,
        "total": total,
        "recovered": recovered,
        "deaths": deaths,
        "active": active,
      };
}

class Statewise extends StatefulWidget {
  @override
  _StatewiseState createState() => _StatewiseState();
}

class _StatewiseState extends State<Statewise> {
  Data _datafromApi;
  bool _isloading;

  @override
  void initState() {
    super.initState();

    _isloading = true;
    ApiServices.getDataFromAPI().then((data) {
      setState(() {
        _datafromApi = data;
        _isloading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_isloading) {
      return Container(
        child: Center(
          child: CircularProgressIndicator(),
        ),
      );
    } else {
      return Scaffold(
        body: ListView.builder(
            itemCount:
                _datafromApi == null ? 0 : _datafromApi.data.regional.length,
            itemBuilder: (context, index) {
              return ListTile(
                  title: Text(
                _datafromApi.data.regional[index].loc.toString(),
                style: TextStyle(color: Colors.black),
              ));
            }),
      );
    }
  }
}
0
Viren V Varasadiya 10 may. 2020 a las 12:24

Lo que estas haciendo es

List<Data> data = Data();
//trying to assign a Data to List of Data: List<Data>

//which is very similar to
List<String> aString = String();
//String should be treated as String but you are treating it as List<String>

Esto funcionará

Data data = Data()
//in your case
Data data = dataFromJson();
0
iamyadunandan 10 may. 2020 a las 12:54

Inicialmente, cuando golpeas la API, obtienes una respuesta como un solo objeto completo

var data = dataFromJson(response.body);

Los datos anteriores son el objeto único y no la lista de objetos Lista Así que inicialmente puede obtener el objeto completo. He hecho un ejemplo a continuación basado en su ejemplo escrito.

Clase de modelo basada en los datos json

// To parse this JSON data, do
//
//     final data = dataFromJson(jsonString);

import 'dart:convert';

Data dataFromJson(String str) => Data.fromJson(json.decode(str));

String dataToJson(Data data) => json.encode(data.toJson());

class Data {
    bool success;
    DataClass data;
    DateTime lastRefreshed;
    DateTime lastOriginUpdate;

    Data({
        this.success,
        this.data,
        this.lastRefreshed,
        this.lastOriginUpdate,
    });

    factory Data.fromJson(Map<String, dynamic> json) => Data(
        success: json["success"],
        data: DataClass.fromJson(json["data"]),
        lastRefreshed: DateTime.parse(json["lastRefreshed"]),
        lastOriginUpdate: DateTime.parse(json["lastOriginUpdate"]),
    );

    Map<String, dynamic> toJson() => {
        "success": success,
        "data": data.toJson(),
        "lastRefreshed": lastRefreshed.toIso8601String(),
        "lastOriginUpdate": lastOriginUpdate.toIso8601String(),
    };
}

class DataClass {
    Summary summary;
    List<UnofficialSummary> unofficialSummary;
    List<Regional> regional;

    DataClass({
        this.summary,
        this.unofficialSummary,
        this.regional,
    });

    factory DataClass.fromJson(Map<String, dynamic> json) => DataClass(
        summary: Summary.fromJson(json["summary"]),
        unofficialSummary: List<UnofficialSummary>.from(json["unofficial-summary"].map((x) => UnofficialSummary.fromJson(x))),
        regional: List<Regional>.from(json["regional"].map((x) => Regional.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "summary": summary.toJson(),
        "unofficial-summary": List<dynamic>.from(unofficialSummary.map((x) => x.toJson())),
        "regional": List<dynamic>.from(regional.map((x) => x.toJson())),
    };
}

class Regional {
    String loc;
    int confirmedCasesIndian;
    int discharged;
    int deaths;
    int confirmedCasesForeign;
    int totalConfirmed;

    Regional({
        this.loc,
        this.confirmedCasesIndian,
        this.discharged,
        this.deaths,
        this.confirmedCasesForeign,
        this.totalConfirmed,
    });

    factory Regional.fromJson(Map<String, dynamic> json) => Regional(
        loc: json["loc"],
        confirmedCasesIndian: json["confirmedCasesIndian"],
        discharged: json["discharged"],
        deaths: json["deaths"],
        confirmedCasesForeign: json["confirmedCasesForeign"],
        totalConfirmed: json["totalConfirmed"],
    );

    Map<String, dynamic> toJson() => {
        "loc": loc,
        "confirmedCasesIndian": confirmedCasesIndian,
        "discharged": discharged,
        "deaths": deaths,
        "confirmedCasesForeign": confirmedCasesForeign,
        "totalConfirmed": totalConfirmed,
    };
}

class Summary {
    int total;
    int confirmedCasesIndian;
    int confirmedCasesForeign;
    int discharged;
    int deaths;
    int confirmedButLocationUnidentified;

    Summary({
        this.total,
        this.confirmedCasesIndian,
        this.confirmedCasesForeign,
        this.discharged,
        this.deaths,
        this.confirmedButLocationUnidentified,
    });

    factory Summary.fromJson(Map<String, dynamic> json) => Summary(
        total: json["total"],
        confirmedCasesIndian: json["confirmedCasesIndian"],
        confirmedCasesForeign: json["confirmedCasesForeign"],
        discharged: json["discharged"],
        deaths: json["deaths"],
        confirmedButLocationUnidentified: json["confirmedButLocationUnidentified"],
    );

    Map<String, dynamic> toJson() => {
        "total": total,
        "confirmedCasesIndian": confirmedCasesIndian,
        "confirmedCasesForeign": confirmedCasesForeign,
        "discharged": discharged,
        "deaths": deaths,
        "confirmedButLocationUnidentified": confirmedButLocationUnidentified,
    };
}

class UnofficialSummary {
    String source;
    int total;
    int recovered;
    int deaths;
    int active;

    UnofficialSummary({
        this.source,
        this.total,
        this.recovered,
        this.deaths,
        this.active,
    });

    factory UnofficialSummary.fromJson(Map<String, dynamic> json) => UnofficialSummary(
        source: json["source"],
        total: json["total"],
        recovered: json["recovered"],
        deaths: json["deaths"],
        active: json["active"],
    );

    Map<String, dynamic> toJson() => {
        "source": source,
        "total": total,
        "recovered": recovered,
        "deaths": deaths,
        "active": active,
    };
}

A continuación se muestra la llamada de servicio API

class ApiServices {

  static const String url = 'https://api.rootnet.in/covid19-in/stats/latest';
static Future<Data> getDataFromAPI() async {
    try {
      final response = await http.get(url);
      if (200 == response.statusCode) {
        final Data data = dataFromJson(response.body);
        //regionalData = data.data.regional;
        // And make the return value as List<Regional> or send the complete object which is benefiicial
        return data;
      } else {
        return null;
      }
    } catch (e) {
      return null;
    }
  }
}

Y, por último, la interfaz de usuario que se muestra a continuación:

oid main()=> runApp(Statewise());



class Statewise extends StatefulWidget {
  @override
  _StatewiseState createState() => _StatewiseState();
}

class _StatewiseState extends State<Statewise> {
  Data responseData;
  bool _isloading;
  List<Regional> regionalData;

  @override
  void initState() {
    super.initState();

    _isloading = true;
    ApiServices.getDataFromAPI().then((data) {
      // you can  initially get the regional data from the getDataFromAPI() method
      setState(() {
        responseData = data;// here you get the complete object 
              // here you can also get the  regional data only  from below code 
           //regionalData = data.data.regional; and assign to the List<Regional>
        _isloading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_isloading) {
      return Container(
        child: Center(
          child: CircularProgressIndicator(),
        ),
      );
    } else {
      return MaterialApp(
              home: Scaffold(
          body: ListView.builder(
              itemCount: responseData.data.regional == null ? 0 : responseData.data.regional.length,
              itemBuilder: (context, index) {
                var region = responseData.data.regional[index];
                //Data datas = _datafromApi[index];
                //print(datas?.toString() ?? "Empty");
                return ListTile(
                    title: Text(
                  region.loc.toString(),
                  style: TextStyle(color: Colors.black),
                ));
              }),
        ),
      );
    }
  }
}

Echa un vistazo y avísame si tienes problemas.

0
sagar acharya 10 may. 2020 a las 13:16