Json serialization returns: type 'Null' is not a subtype of type 'String'

Issue

So I’m trying to build a list (of any kind) from a Json list object in flutter, I’m getting it using REST api the response is a Json list with the fields: type, contact {first_name, last_name}, created_at, uuid.

using this code I’m fetching the data and parsing it to custom data type

import 'dart:convert';
import 'package:connectix/models/calls.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

class ContactService {
static String _url = "https://api.voipappz.io/tasks//connectix_conversations_recent";

static Future browse() async{
var channel = IOWebSocketChannel.connect(Uri.parse(_url));

}
}

List<CallType> parseCalls(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();

return parsed.map<CallType>((json) => CallType.fromJson(json)).toList();
}

Future<List<CallType>> fetchCalls(http.Client client) async {
final response = await client
  .get(Uri.parse("https://api.voipappz.io/tasks//connectix_conversations_recent"));
// Use the compute function to run parsePhotos in a separate isolate.
return compute(parseCalls, response.body);
}

That’s the data type model

class CallType {
final String type;
final String first_name, last_name;
final String created;

CallType({
required this.type,
required this.first_name,
required this.last_name,
required this.created,
});

factory CallType.fromJson(Map<String, dynamic> json){
return CallType(
  type: json['type'],
  first_name: json['contact.first_name'],
  last_name: json['contact.last_name'],
  created: json['created_at'],
);
} 

}

and this is the code for the widget I’m trying to display and returns me the error in the question title

class CallsList extends StatelessWidget {
final List<CallType> calls;

CallsList({Key? key, required this.calls}) : super(key: key);

@override
Widget build(BuildContext context) {
return GridView.builder(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
  ),
  itemCount: calls.length,
  itemBuilder: (context, index) {
    return Text(calls[index].type);
  },
);
}
}


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

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

class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.orange,
    appBar: AppBar(
      title: Text('hello'),
    ),
    body: FutureBuilder<List<CallType>>(
      future: fetchCalls(http.Client()),
      builder: (context, snapshot) {
        if (snapshot.hasError) print(snapshot.error);

      return snapshot.hasData
          ? CallsList(calls: snapshot.data!)
          : Center(child: CircularProgressIndicator());
    },
  ),
);
}
}

Solution

You marked all attributes of CallType as required. It looks like the API is not returning data for one (or more) of these attributes.

You need either to mark them as optional (remove required and make them of type String?), or take care that your API is always responding with data.

Answered By – Stefan Galler

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *