Flutter error: type 'int' is not a subtype of type 'String' in type cast

33,177

Solution 1

Your dateCreated has an int timestamp but your category model has a string data type. Change String dateCreated; and String lastUpdated; in the category model to int dateCreated and int lastUpdated respectively

Solution 2

Best workaround I found

int pageCount = int.parse(snapshot.data.data['totalPg'].toString());

Solution 3

The best approach is to use annotations from this package. For example

@JsonSerializable(explicitToJson: true)
class Artist {
  String name;
  String listeners;
  @JsonKey(defaultValue: '')
  String mid;
}

will generate the code with null check for the mid field

Artist _$ArtistFromJson(Map<String, dynamic> json) {
  return Artist(
    name: json['name'] as String,
    listeners: json['listeners'] as String,
    mid: json['mid'] as String? ?? '',
}
Share:
33,177
PeakGen
Author by

PeakGen

CTO

Updated on March 09, 2022

Comments

  • PeakGen
    PeakGen about 2 years

    I am trying to get data from a REST API using a Flutter app. I am building model classes in json_serializable way. Below is my code.

    main.dart

    import 'package:flutter/material.dart';
    import 'dart:convert' as convert;
    import 'package:http/http.dart' as http;
    
    import './category.dart';
    
    void main()
    {
      runApp(MyApp());
    }
    
    class MyApp extends StatefulWidget
    {
      @override
      State<StatefulWidget> createState() {
        // TODO: implement createState
        return HttpTestState();
      }
    
    }
    
    class HttpTestState extends State<MyApp>
    {
      @override
      Widget build(BuildContext context) {
    
        //bookFind();
        productFind();
    
        return MaterialApp(
          title: 'Flutter layout demo',
          home: Scaffold(
    
            body: Scaffold(appBar: AppBar(title: Text("HTTP Test"),),
        body: Container(child: Text("data"),),)
            ),
    
        );
    
      }
    
    productFind() async{
      var url = "http://10.0.2.2:8080/xxx/rest/productCategory/getAllProductCategories";
    
      // Await the http get response, then decode the json-formatted responce.
      var response = await http.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
      if (response.statusCode == 200) {
       print("Response Body: "+response.body);
    
         List userMap = convert.jsonDecode(response.body);
         Category ProductCategories = new Category.fromJson(userMap[0]);
    
      } else {
        print("Request failed with status: ${response.statusCode}.");
      }
    }
    
    
    }
    

    category.dart (model class)

    import 'package:json_annotation/json_annotation.dart';
    
    part 'category.g.dart';
    
    @JsonSerializable()
    
    
    class Category
    {
      int idproductCategory;
      String categoryName;
      String imageURL;
      String deleteTimestamp;
      String dateCreated;
      String lastUpdated;
    
      Category(this.idproductCategory, this.categoryName, this.imageURL, this.deleteTimestamp, this.dateCreated, this.lastUpdated);
    
      factory Category.fromJson(Map<String, dynamic> json) => _$CategoryFromJson(json);
    
      Map<String, dynamic> toJson() => _$CategoryToJson(this);
    }
    

    category.g.dart (the class generated by json_serializable)

    // GENERATED CODE - DO NOT MODIFY BY HAND
    
    part of 'category.dart';
    
    // **************************************************************************
    // JsonSerializableGenerator
    // **************************************************************************
    
    Category _$CategoryFromJson(Map<String, dynamic> json) {
      return Category(
          json['idproductCategory'] as int,
          json['categoryName'] as String,
          json['imageURL'] as String,
          json['deleteTimestamp'] as String,
          json['dateCreated'] as String,
          json['lastUpdated'] as String);
    }
    
    Map<String, dynamic> _$CategoryToJson(Category instance) => <String, dynamic>{
          'idproductCategory': instance.idproductCategory,
          'categoryName': instance.categoryName,
          'imageURL': instance.imageURL,
          'deleteTimestamp': instance.deleteTimestamp,
          'dateCreated': instance.dateCreated,
          'lastUpdated': instance.lastUpdated
        };
    

    The JSON response to the given URL should be like below.

    [{
            "idproductCategory": 1,
            "categoryName": "Fruits",
            "imageURL": "https://images.unsplash.com/photo-1512621776951-a57141f2eefd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
            "deleteTimestamp": null,
            "dateCreated": 1550056389000,
            "lastUpdated": 1550056389000
        },
        {
            "idproductCategory": 2,
            "categoryName": "Vegetables",
            "imageURL": "https://images.unsplash.com/photo-1522184216316-3c25379f9760?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
            "deleteTimestamp": null,
            "dateCreated": 1550056389000,
            "lastUpdated": 1550056389000
        }]
    

    However when I run my code I get the following error.

    E/flutter ( 6448): [ERROR:flutter/shell/common/shell.cc(178)] Dart Error: Unhandled exception:
    E/flutter ( 6448): type 'int' is not a subtype of type 'String' in type cast
    E/flutter ( 6448): #0      _$CategoryFromJson 
    E/flutter ( 6448): #1      new Category.fromJson 
    E/flutter ( 6448): #2      HttpTestState.productFind 
    E/flutter ( 6448): <asynchronous suspension>
    E/flutter ( 6448): #3      HttpTestState.build 
    E/flutter ( 6448): #4      StatefulElement.build 
    E/flutter ( 6448): #5      ComponentElement.performRebuild 
    E/flutter ( 6448): #6      Element.rebuild 
    E/flutter ( 6448): #7      BuildOwner.buildScope 
    E/flutter ( 6448): #8      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame 
    E/flutter ( 6448): #9      _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback 
    E/flutter ( 6448): #10     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback 
    E/flutter ( 6448): #11     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame 
    E/flutter ( 6448): #12     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> 
    E/flutter ( 6448): #13     Timer._createTimer.<anonymous closure> (dart:async/runtime/libtimer_patch.dart:21:15)
    E/flutter ( 6448): #14     _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19)
    E/flutter ( 6448): #15     _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5)
    E/flutter ( 6448): #16     _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
    

    Why is this?

  • PeakGen
    PeakGen about 5 years
    Amazing, yes that worked. However they are TimeStamps, more preferably SQLTimeStamps. Do you know how can handle this type in Flutter?
  • nonybrighto
    nonybrighto about 5 years
    try changing int to DateTime and see if it works. If it doesn't, I think there should be a workaround by creating your own fromJson or creating a method within your model to convert the int to dateTime. Let me know if it doesn't work. You might need to create a different question for it.
  • PeakGen
    PeakGen about 5 years
    I think it is not possible to auto convert. You have to get it in int and convert to DateTime
  • nonybrighto
    nonybrighto about 5 years
    Ok. I will check it out and get back to you.
  • nonybrighto
    nonybrighto about 5 years
    I've created a question to show how to do the conversion stackoverflow.com/questions/55328064/…