flutterfirebase-realtime-databaseflutter-charts

Unhandled Exception: type '(dynamic) => ReadingModel' is not a subtype of type '(String, dynamic) = > MapEntry<dynamic, dynamic>' of 'transform'


I am having error : Unhandled Exception: type '(dynamic) => ReadingModel' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform' when I want to used the data from Realtime Firebase Database to be displayed in charts.

Below is the Model

import 'dart:convert';

List<ReadingModel> readingModelFromJson(String str) => List<ReadingModel>.from(
    json.decode(str).map((x) => ReadingModel.fromJson(x)));

String readingModelToJson(List<ReadingModel> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class ReadingModel {
  ReadingModel(
      { required this.GPS,
        required this.MQ2,
        required this.MQ9,
        required this.Time
      });

  String GPS;
  String MQ2;
  String MQ9;
  String Time;




  factory ReadingModel.fromJson(Map<String, dynamic> json) => ReadingModel(
      GPS: json['GPS'],
      MQ2: json['MQ2'],
      MQ9: json['MQ9'],
      Time: json['Time']
  );

  Map<String, dynamic> toJson() => {
    "GPS": GPS,
    "MQ2": MQ2,
    "MQ9": MQ9,
    "Time": Time
  };
}

Below is the code to display the graph

import 'package:flutter/material.dart';
import 'package:safecar/reading_model.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:http/http.dart' as http;

class TestingPage2 extends StatefulWidget {
  @override
  _TestingPage2 createState() => _TestingPage2();
}

class _TestingPage2 extends State<TestingPage2> {
  @override
  void initState() {
    setState(() {
      getData();
    });
    super.initState();
  }

  bool loading = true;
  List<ReadingModel> statistikReading = [];

  void getData() async {
    var url = Uri.parse(
        'https://car-air-quality-monitori-95b96-default-rtdb.asia-southeast1.firebasedatabase.app/.json');

    var response = await http.get(url);

    if (response.statusCode == 200) {

      List<ReadingModel> tempdata = readingModelFromJson(response.body);
      setState(() {
        statistikReading = tempdata;
        loading = false;
      });

    } else {
      print("Hello");
    }
  }

  List<charts.Series<ReadingModel, int>> _createSampleDataLine() {
    return [
      charts.Series<ReadingModel, int>(
        data: statistikReading,
        id: 'sales',
        colorFn: (_, __) =>
            charts.ColorUtil.fromDartColor(Color(0XFF35BBCA)),
        domainFn: (ReadingModel readingModel, _) => int.parse(readingModel.Time),
        measureFn: (ReadingModel readingModel, _) => int.parse(readingModel.MQ2),
      )
    ];
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
        body: Column(
          children: <Widget>[
            Text(
              "MQ2 Readings",
              style: TextStyle(fontSize: 12.0),
            ),
            Expanded(
              child: charts.LineChart(
                _createSampleDataLine(),
                animate: true,
              ),
            ),
          ],
        ));
  }
}

This is the link to the sample data

Sample Data Link

I am still new to Flutter. Hope to get help to solve this issue.


Solution

  • change readingModelFromJson to this:

    List<ReadingModel> readingModelFromJson(String str) => List<ReadingModel>.from(
      json.decode(str)['ESP32_APP'].entries.map((x) => ReadingModel.fromJson(x.value))
    );