[Solved] Android Studio API Call

Question

Asked by mhmh on December 14, 2021 (source).

I basically have everything functioning following this tutorial on how to implement a API in flutter: https://docs.flutter.dev/cookbook/networking/fetch-data. I followed the tutorial but i get an error message "type 'null is not a subtype of 'String'". I have tried adding additional parameters to the header, but that haven't solved the problem. The API im using is a car registry, where you can type in a numberplate and get all the details for a vehicle.

  final response = await http
      .get(Uri.parse('https://v1.motorapi.dk/vehicles/CZ33849'),
       headers: {"X-AUTH-TOKEN": "rfrzsucnc7eo3m5hcmq6ljdzda1lz793",
        "Content-Type": "application/json",
        "Accept": "application/json",
      });

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Album.fromJson(jsonDecode(response.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

//headers: {"X-AUTH-TOKEN": "rfrzsucnc7eo3m5hcmq6ljdzda1lz793"}

class Album {
  final String registration_number;
  final String status;
  final String type;
  final String use;
  final String first_registration;
  final String vin;
  final int doors;
  final String make;
  final String model;
  final String variant;
  final String model_type;
  final String color;
  final String chasis_type;
  final String engine_power;
  final String fuel_type;
  final String RegistreringssynToldsyn;
  final String date;
  final String result;

  Album({
    required this.registration_number,
    required this.status,
    required this.type,
    required this.use,
    required this.first_registration,
    required this.vin,
    required this.doors,
    required this.make,
    required this.model,
    required this.variant,
    required this.model_type,
    required this.color,
    required this.chasis_type,
    required this.engine_power,
    required this.fuel_type,
    required this.RegistreringssynToldsyn,
    required this.date,
    required this.result,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      registration_number: json['registration_number'],
      status: json['status'],
      type: json['type'],
      use: json['use'],
      first_registration: json['first_registration'],
      vin: json['vin'],
      doors: json['doors'],
      make: json['make'],
      model: json['model'],
      variant: json['variant'],
      model_type: json['model_type'],
      color: json['color'],
      chasis_type: json['chasis_type'],
      engine_power: json['engine_power'],
      fuel_type: json['fuel_type'],
      RegistreringssynToldsyn: json['RegistreringssynToldsyn'],
      date: json['date'],
      result: json['result'],
    );
  }
}

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  late Future<Album> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = fetchAlbum();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Fetch Data Example'),
        ),
        body: Center(
          child: FutureBuilder<Album>(
            future: futureAlbum,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data!.registration_number);
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }

              // By default, show a loading spinner.
              return const CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}

And the Json response from the API (I tested the API in python):

{'registration_number': 'CZ33849', 'status': 'Registreret', 'status_date': '2021-03-18T10:53:23.000+01:00', 'type': 'Personbil', 'use': 'Privat personkørsel', 'first_registration': '2020-03-17+01:00', 'vin': 'WVWZZZAWZLY087322', 'own_weight': None, 'total_weight': 1650, 'axels': 2, 'pulling_axels': 1, 'seats': 5, 'coupling': False, 'trailer_maxweight_nobrakes': 590, 'trailer_maxweight_withbrakes': 1000, 'doors': 4, 'make': 'VOLKSWAGEN', 'model': 'POLO', 'variant': '1,0', 'model_type': 'AW', 'model_year': 0, 'color': None, 'chassis_type': 'Hatchback', 'engine_cylinders': 3, 'engine_volume': 999, 'engine_power': 70, 'fuel_type': 'Benzin', 'registration_zipcode': '', 'vehicle_id': 9000000003974700, 'mot_info': {'type': 'RegistreringssynToldsyn', 'date': '2021-03-16', 'result': 'Godkendt', 'status': 'Aktiv', 'status_date': '2021-03-16'}}

Answer

Question answered by Diwyansh (source).

You have marked all the fields in your Album class as required just make them nullable so that is API returns something null then class can handle that as well. Make following changes to your class

class Album {
  final String? registration_number;
  final String? status;
  final String? type;
  final String? use;
  final String? first_registration;
  final String? vin;
  final int? doors;
  final String? make;
  final String? model;
  final String? variant;
  final String? model_type;
  final String? color;
  final String? chasis_type;
  final String? engine_power;
  final String? fuel_type;
  final String? RegistreringssynToldsyn;
  final String? date;
  final String? result;

  Album({
    this.registration_number,
    this.status,
    this.type,
    this.use,
    this.first_registration,
    this.vin,
    this.doors,
    this.make,
    this.model,
    this.variant,
    this.model_type,
    this.color,
    this.chasis_type,
    this.engine_power,
    this.fuel_type,
    this.RegistreringssynToldsyn,
    this.date,
    this.result,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      registration_number: json['registration_number'],
      status: json['status'],
      type: json['type'],
      use: json['use'],
      first_registration: json['first_registration'],
      vin: json['vin'],
      doors: json['doors'],
      make: json['make'],
      model: json['model'],
      variant: json['variant'],
      model_type: json['model_type'],
      color: json['color'],
      chasis_type: json['chasis_type'],
      engine_power: json['engine_power'],
      fuel_type: json['fuel_type'],
      RegistreringssynToldsyn: json['RegistreringssynToldsyn'],
      date: json['date'],
      result: json['result'],
    );
  }
}
ANDROID-STUDIO FLUTTER
SHARE: