Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: 'NoSuchMethodError' is not a subtype of type String

Tags:

flutter

dart

I currently have an app that pulls a list of providers through JSON.

This is the JSON file.

hospitals.json

{
"Johor": [
    {
      "Name": "KLINIK TAJ (MUAR)",
      "TPA Customer ID": "1168",
      "Organization Type": "Clinic",
      "Organization Subtype": "GP",
      "Street (Billing)": "35a, jalan abdullah ",
      "City (Billing)": "muar",
      "Postal Code (Billing)": "84000",
      "State (Billing)": "Johor",
      "Country (Billing)": "Malaysia",
      "Coordinates": {
        "Latitude": "2.041875",
        "Longitude": "102.568235"
      }
    },
    {
      "Name": "KLINIK TAJ (PAGOH)",
      "TPA Customer ID": "1169",
      "Organization Type": "Clinic",
      "Organization Subtype": "GP",
      "Street (Billing)": "100 Main Road Pagoh",
      "City (Billing)": "Muar",
      "Postal Code (Billing)": "84600",
      "State (Billing)": "Johor",
      "Country (Billing)": "Malaysia",
      "Coordinates": {
        "Latitude": "2.148342",
        "Longitude": "102.771002"
      }
    }
  ],
  "Kedah": [
    {
      "Name": "KLINIK TAN",
      "TPA Customer ID": "8423",
      "Organization Type": "Clinic",
      "Organization Subtype": "GP",
      "Street (Billing)": "62 Jalan Raya",
      "City (Billing)": "Kulim",
      "Postal Code (Billing)": "9000",
      "State (Billing)": "Kedah",
      "Coordinates": {
        "Latitude": "5.366739",
        "Longitude": "100.553988"
      }
    },
    {
      "Name": "KLINIK SHAN",
      "TPA Customer ID": "1685",
      "Organization Type": "Clinic",
      "Organization Subtype": "GP",
      "Street (Billing)": "L. C. 19, Jalan Lunas,",
      "City (Billing)": "Padang Serai",
      "Postal Code (Billing)": "9000",
      "State (Billing)": "Kedah",
      "Coordinates": {
        "Latitude": "5.402193",
        "Longitude": "100.555209"
      }
    }
  ]
}

This is the model class of the JSON

new_accounts_model.dart

class Johor {

  List<AccountInfo> accountinfo;

  Johor({this.accountinfo});

  factory Johor.fromJson(Map<String, dynamic> json){

    var accJson = json["Johor"] as List;
    List<AccountInfo> accList = accJson.map((i) => AccountInfo.fromJson(i)).toList();

    return Johor(
        accountinfo: accList
    );
  }
}

class AccountInfo{

  String name;
  String id;
  String orgtype;
  String subtype;
  String street;
  String city;
  String country;
  Coordinates coordinates;

  AccountInfo({this.name, this.id, this.orgtype, this.subtype, this.street, this.city, this.country, this.coordinates});

  factory AccountInfo.fromJson(Map<String, dynamic> json){

    return AccountInfo(
        name: json["Name"],
        id: json["TPA Customer ID"],
        orgtype: json["Organization Type"],
        subtype: json["Organization Subtype"],
        street: json["Street (Billing)"],
        city: json["City (Billing)"],
        country: json["State (Billing)"],
        coordinates: Coordinates.fromJson(json["Coordinate"])
    );
  }
}

class Coordinates{

  String lat;
  String lng;

  Coordinates({this.lat, this.lng});

  factory Coordinates.fromJson(Map<String, dynamic> json){

    return Coordinates(
        lat: json["Latitude"],
        lng: json["Longitude"]
    );
  }
}

And this is the dart file used to bring out the JSON file.

list.dart

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
import 'package:emas_app/model/new_accounts_model.dart';

Future<String> _loadAsset() async{
  return await rootBundle.loadString('Assets/hospitals.json');
}

//Not working future
Future<Johor> loadJohor() async{

  final response = await _loadAsset();
  final jsonResponse = json.decode(response);

  Johor johor = new Johor.fromJson(jsonResponse);

  return johor;
}

class ProviderList extends StatefulWidget {

  @override
  ListState createState() {
    return new ListState();
  }
}

class ListState extends State<ProviderList> {

  @override
  Widget build(BuildContext context) {

    List<Widget> widgets = [];

    launchMapUrl(String lat, String lng) async{
      String geoUri = "https://maps.google.com/maps?q=loc:$lat,$lng";
      if (await canLaunch(geoUri)) {
        print("Can launch");
        await launch(geoUri);
      } else {
        print("Could not launch");
        throw 'Could not launch Maps';
      }
    }

    //method to bring out dialog
    makeDialog(String address){
      showDialog(
          context: context,
          builder: (_) => new SimpleDialog(
            contentPadding: EdgeInsets.only(left: 30.0, top: 30.0),
            children: <Widget>[
              new Text("Address: $address",
                style: TextStyle(
                  fontWeight: FontWeight.bold
                ),
              ),
              new ButtonBar(
                children: <Widget>[
                  new IconButton(
                      icon: Icon(Icons.close),
                      onPressed: (){
                        Navigator.pop(context);
                      }
                      )
                ],
              )
            ],
          )
      );
    }

    widgets.add(new ExpansionTile(
        title: new Text("Not working state"),
        children: <Widget>[
          new FutureBuilder<Johor>(
              future: loadJohor(),
              builder: (context, snapshot){
                if(snapshot.hasData){

                  return new ListView.builder(
                      shrinkWrap: true,
                      itemCount: snapshot.data.accountinfo.length,
                      itemBuilder: (context, index){

                        String username = snapshot.data.accountinfo[index].name;
                        String address = snapshot.data.accountinfo[index].street;
                        String lat = snapshot.data.accountinfo[index].coordinates.lat;
                        String lng = snapshot.data.accountinfo[index].coordinates.lng;

                        return new ListTile(
                            title: new Text(username),
                            trailing: new Row(
                              mainAxisSize: MainAxisSize.min,
                              mainAxisAlignment: MainAxisAlignment.end,
                              children: <Widget>[
                                new IconButton(
                                    icon: Icon(Icons.info),
                                    onPressed: (){
                                      makeDialog(address);
                                    }
                                ),
                                new IconButton(
                                    icon: Icon(Icons.directions),
                                    onPressed: (){
                                      launchMapUrl(lat, lng);
                                    }
                                )
                              ],
                            )
                        );
                      });
                }else if(snapshot.hasError){
                  return new Center(
                    child: new Text(snapshot.error),
                  );
                }
              })
        ]
    ));

    //empty list
    widgets.add(new ExpansionTile(
        title: new Text("Pahang")));

    return new Scaffold(
      appBar: new AppBar(title: new Text("Providers")),
      body: new Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: widgets,
      )
    );
  }
}

This is the error currently faced:

NosuchMethod

As the title says, the error is saying its a NoSuchMethodError. Therefore I am unsure as to what is causing this error in the first place.

My current guess is that I am not doing the Model class correctly but it could be something else.

I could really use some help in this case.

like image 644
Asyraf Dayan Avatar asked Sep 13 '18 09:09

Asyraf Dayan


1 Answers

You are using wrong key for Coordinates. You should use Coordinates as its name of key in json. But you are using Coordinate in method factory AccountInfo.fromJson

Update your last line of that method

coordinates: Coordinates.fromJson(json["Coordinates"])
like image 192
Dhiraj Sharma Avatar answered Nov 17 '22 08:11

Dhiraj Sharma