Home > Net >  How to fix error code "type 'null' is not a subtype of type 'map string dynamic
How to fix error code "type 'null' is not a subtype of type 'map string dynamic

Time:11-09

I am trying to print API data from Earthquakes for a school project but it gives me an error:

type 'null' is not a subtype of type 'map string dynamic '.

How to fix this? API is working btw. Here is my code:

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<Album> createAlbum(String events) async {
  final response = await http.get(Uri.parse('https://cdn.knmi.nl/knmi/map/page/seismologie/all_induced.json')); // url api

  if (response.statusCode == 200) {
    // status code moet 200 zijn om uit te printen.

    print(response.body); // in de console word alle data geprint
    final json = jsonDecode(response.body);
    return Album.fromJson(json[0]);

  } else {
    throw Exception(response.statusCode.toString()); // status code word geprint als het niet gelijk is aan 200
  }
}

class Album {
final String events;


  Album({required this.events});

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      events: json['events'] as String,    // variable fact word gepakt om uit te printen

      // place: json['[place]'],
      // generated: json['generated'],
      // coordinates: json['coordinates'],
    );
  }
}

void main() {
  runApp(const MaterialApp(
    title: 'Test', // class om een titel aan te maken in de appbar
    home: FirstRoute(),
  ));
}


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

  @override
  _MyAppState createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<FirstRoute> {
  final TextEditingController _controller = TextEditingController();
  Future <Album>? _futureAlbum;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Honden Feiten',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Honden Feiten'),
        ),
        body: Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.all(9.0),
          child: (_futureAlbum== null ) ? buildColumn() : buildFutureBuilder(),

        ),
      ),
    );
  }

  Column buildColumn() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Image.network('https://e7.pngegg.com/pngimages/496/352/png-clipart-osaka-earthquake-computer-icons-earthquake-engineering-earthquakes-text-logo-thumbnail.png'),
        ElevatedButton(  // knop met de future album word geprint
          onPressed: () {
            setState(() {
              _futureAlbum = createAlbum(_controller.text); // de class wordt geprint waar de variable van de API in staan.
            });
          },
          child: const Text('Klik hier voor een honden feitje! (in het engels)'),

        ),
      ],
    );
  }
// error code of niet
  FutureBuilder<Album> buildFutureBuilder() {
    return FutureBuilder<Album>(
      future: _futureAlbum,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return Text(snapshot.data!.events );


        } else if (snapshot.hasError) {
          return Text('${snapshot.error}');
        }

        return const CircularProgressIndicator();
      },
    );
  }
}

CodePudding user response:

https://github.com/Lavkushwaha/StackOverFlow_Student

First you don't need index in json[0] its not list so you can directly use as : line number 14

return Album.fromJson(json[0]);

then you will error in : line number 31

_CastError (type 'List<dynamic>' is not a subtype of type 'String' in type cast)

cause events is list not string, and you are trying to Map it as string.

ill tell you simple solution

  1. Copy json response from API, go to QuickType -> select dart, create dart model for it

  2. In the success response directly cast model with your json response;

  3. then you can access it in your app

let me know if you need anything else.

Thanks

Added Working code for your project

https://github.com/Lavkushwaha/StackOverFlow_Student

just create a file earthquake.model.dart paste it now in line number 14 change final earthquake = earthquakeFromJson(jsonString);

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

import 'dart:convert';

Earthquake earthquakeFromJson(String str) => Earthquake.fromJson(json.decode(str));

String earthquakeToJson(Earthquake data) => json.encode(data.toJson());

class Earthquake {
    Earthquake({
        this.events,
    });

    final List<Event> events;

    factory Earthquake.fromJson(Map<String, dynamic> json) => Earthquake(
        events: json["events"] == null ? null : List<Event>.from(json["events"].map((x) => Event.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "events": events == null ? null : List<dynamic>.from(events.map((x) => x.toJson())),
    };
}

class Event {
    Event({
        this.date,
        this.depth,
        this.evaluationMode,
        this.lat,
        this.lon,
        this.mag,
        this.place,
        this.time,
        this.type,
    });

    final DateTime date;
    final String depth;
    final EvaluationMode evaluationMode;
    final String lat;
    final String lon;
    final String mag;
    final String place;
    final String time;
    final Type type;

    factory Event.fromJson(Map<String, dynamic> json) => Event(
        date: json["date"] == null ? null : DateTime.parse(json["date"]),
        depth: json["depth"] == null ? null : json["depth"],
        evaluationMode: json["evaluationMode"] == null ? null : evaluationModeValues.map[json["evaluationMode"]],
        lat: json["lat"] == null ? null : json["lat"],
        lon: json["lon"] == null ? null : json["lon"],
        mag: json["mag"] == null ? null : json["mag"],
        place: json["place"] == null ? null : json["place"],
        time: json["time"] == null ? null : json["time"],
        type: json["type"] == null ? null : typeValues.map[json["type"]],
    );

    Map<String, dynamic> toJson() => {
        "date": date == null ? null : "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
        "depth": depth == null ? null : depth,
        "evaluationMode": evaluationMode == null ? null : evaluationModeValues.reverse[evaluationMode],
        "lat": lat == null ? null : lat,
        "lon": lon == null ? null : lon,
        "mag": mag == null ? null : mag,
        "place": place == null ? null : place,
        "time": time == null ? null : time,
        "type": type == null ? null : typeValues.reverse[type],
    };
}

enum EvaluationMode { MANUAL }

final evaluationModeValues = EnumValues({
    "manual": EvaluationMode.MANUAL
});

enum Type { INDUCED_EARTHQUAKE }

final typeValues = EnumValues({
    "induced earthquake": Type.INDUCED_EARTHQUAKE
});

class EnumValues<T> {
    Map<String, T> map;
    Map<T, String> reverseMap;

    EnumValues(this.map);

    Map<T, String> get reverse {
        if (reverseMap == null) {
            reverseMap = map.map((k, v) => new MapEntry(v, k));
        }
        return reverseMap;
    }
}
  • Related