0

I'm building an app to return JSON data from an API. The error occurs when parsing the data for RouteLine.

route_table.dart

class RouteTable {
  int? deliveryPeriod = 0;
  String? driverId = "";
  String? processId = "";
  String? routeId = "";
  RouteLine? routeLines;
  int? status = 0;
  String? vanId = "";

 factory RouteTable.fromJson(Map<String, dynamic> json) {
    return RouteTable(
        deliveryPeriod: json['deliveryPeriod'],
        driverId: json['driverId'],
        processId: json['processId'], 
        routeId: json['routeId'],
        routeLines: json['routeLines'] == null
            ? null
            : RouteLine.fromJson(jsonDecode(json['routeLines'])),
        status: json['status'],
        vanId: json['vanId']);
}

route_line.dart

class RouteLine {
  String? city = "";
  String? custAccount = "";
  String? custName = "";
  String? invoiceId = "";
  DateTime? deliveryDate = initDateTime();
  int? productType = 0;
  String? routeId = "";
  String? salesId = "";
  double? volume = 0.0;
  double? weight = 0.0;

 factory RouteLine.fromJson(Map<String, dynamic> json) {
    return new RouteLine(
      city: json['city'] as String,
      custAccount: json['custAccount'] as String,
      custName: json['custName'] as String,
      invoiceId: json['invoiceId'] as String,
      deliveryDate: json['deliveryDate'] as DateTime,
      productType: json['productType'] as int,
      routeId: json['routeId'] as String,
      salesId: json['salesId'] as String,
      volume: json['volume'] as double,
      weight: json['weight'] as double,
    );
}

main.dart file where I'm trying to display the results.

import 'dart:io';
import 'package:flutter/material.dart';
import 'route_line.dart';
import 'route_table.dart';
import 'networking.dart';

void main() {
  HttpOverrides.global = new MyHttpOverrides();
  runApp(MyApp());
}



class MyApp extends StatelessWidget {
// to set the root of app.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.green,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'API Demo Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, this.title = ""}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late Future<RouteTable> futureRouteTable;
  @override
  void initState() {
    super.initState();
    futureRouteTable = fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text("Flutter - API Implementation"),
      ),
      body: Center(
          child: // build list view & manage states
              FutureBuilder<RouteTable>(
        future: futureRouteTable,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            final RouteTable? posts = snapshot.data;
            if (snapshot.data != null) {
              return Text(snapshot.data!.routeId.toString());
            }
            return Text('No Data');
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      )),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {},
        label: Icon(Icons.cancel),
        backgroundColor: Colors.green,
      ),
    );
  }

Future<RouteTable> fetchData() async {
  final response =
      await http.get(Uri.parse('https://10.0.2.2:7038/api/route/1?siteId=1'));

  try {
    if (response.statusCode == 200) {
      // If the server did return a 200 OK response,
      // then parse the JSON.
      return RouteTable.fromJson(jsonDecode(response.body));
    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
      throw Exception('Failed to load route');
    }
  } catch (e) {
    print(e);
  }
  return new RouteTable(
      deliveryPeriod: 0,
      driverId: "",
      processId: "",
      routeId: "",
      routeLines: new RouteLine(
          city: "",
          custAccount: "",
          custName: "",
          invoiceId: "",
          deliveryDate: new DateTime(2022),
          productType: 0,
          routeId: "",
          salesId: "",
          volume: 0.0,
          weight: 0.0),
      status: 0,
      vanId: "");
}
}

The JSON data being returned

{
   "deliveryPeriod":1,
   "driverId":"",
   "processId":"PRO000492",
   "routeId":"ROU001858",
   "routeLines":[
      {
         "city":"Naxxar",
         "custAccount":"CUST010922",
         "custName":"",
         "deliveryDate":"2021-12-06T12:00:00",
         "invoiceId":"",
         "productType":0,
         "routeId":"ROU001858",
         "salesId":"SO002579",
         "volume":0.019448889,
         "weight":15.225435
      }
   ],
   "status":30,
   "vanId":"TFI 943"
}

I'm running into the following error when trying to parse RouteLine inside RouteTable.fromJson.

type 'List<dynamic>' is not a subtype of type 'String'

Tried without the jsonDecode and get a similar error.

type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'

How do I turn it to a List? What am I missing?

1

1 Answer 1

1

You can use QuickType to convert JSON into Dart Models. Here is your dart data model which I generated through it.

import 'dart:convert';

class RouteTable {
    RouteTable({
        this.deliveryPeriod,
        this.driverId,
        this.processId,
        this.routeId,
        this.routeLines,
        this.status,
        this.vanId,
    });

    int deliveryPeriod;
    String driverId;
    String processId;
    String routeId;
    List<RouteLine> routeLines;
    int status;
    String vanId;

    factory RouteTable.fromJson(Map<String, dynamic> json) => RouteTable(
        deliveryPeriod: json["deliveryPeriod"],
        driverId: json["driverId"],
        processId: json["processId"],
        routeId: json["routeId"],
        routeLines: List<RouteLine>.from(json["routeLines"].map((x) => RouteLine.fromJson(x))),
        status: json["status"],
        vanId: json["vanId"],
    );

    Map<String, dynamic> toJson() => {
        "deliveryPeriod": deliveryPeriod,
        "driverId": driverId,
        "processId": processId,
        "routeId": routeId,
        "routeLines": List<dynamic>.from(routeLines.map((x) => x.toJson())),
        "status": status,
        "vanId": vanId,
    };
}

class RouteLine {
    RouteLine({
        this.city,
        this.custAccount,
        this.custName,
        this.deliveryDate,
        this.invoiceId,
        this.productType,
        this.routeId,
        this.salesId,
        this.volume,
        this.weight,
    });

    String city;
    String custAccount;
    String custName;
    DateTime deliveryDate;
    String invoiceId;
    int productType;
    String routeId;
    String salesId;
    double volume;
    double weight;

    factory RouteLine.fromJson(Map<String, dynamic> json) => RouteLine(
        city: json["city"],
        custAccount: json["custAccount"],
        custName: json["custName"],
        deliveryDate: DateTime.parse(json["deliveryDate"]),
        invoiceId: json["invoiceId"],
        productType: json["productType"],
        routeId: json["routeId"],
        salesId: json["salesId"],
        volume: json["volume"].toDouble(),
        weight: json["weight"].toDouble(),
    );

    Map<String, dynamic> toJson() => {
        "city": city,
        "custAccount": custAccount,
        "custName": custName,
        "deliveryDate": deliveryDate.toIso8601String(),
        "invoiceId": invoiceId,
        "productType": productType,
        "routeId": routeId,
        "salesId": salesId,
        "volume": volume,
        "weight": weight,
    };
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.