'Expected a value of type 'int', but got one of type 'Null'

I'm trying to pull data using github repo tree json with dart (flutter). Expected a value of type 'int', but got one of type 'Null'.

        Expanded(
              child: SingleChildScrollView(
                scrollDirection: Axis.vertical,
                child: Container(
                  ..
                  child: getFileList(),
                ),
              ),
            ),

Expanded in scaffold. I'm not sure I'm using snapshot.data.tree correctly. I want to get all file information.

FutureBuilder getFileList() {
    return FutureBuilder<RepoTree>(
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.hasData) {
          return Center(
              child: Text(
            "File List\n" + snapshot.data.tree,
          ));
        } else if (snapshot.hasError) {
          return Center(
              child: Text("Error in getFileList " + snapshot.error.toString()));
        } else {
          return const Center(
            child: CircularProgressIndicator(),
          );
        }
      },
      future: getResForRepoList(),
    );
  }

  Future<RepoTree> getResForRepoList() async {
    final response = await http.get(Uri.parse(
        'https://api.github.com/repos/satyasashi/todo_basic/git/trees/master?recursive=1')); 

    if (response.statusCode == 200) {
      return RepoTree.fromJson(
          json.decode(response.body));
    } else {
      throw Exception('Exception in getResForRepoList');
    }
  }

My classes

class RepoTree {
  String sha;
  String url;
  List<RepoInside> tree;
  bool truncated;

  RepoTree({
    required this.sha,
    required this.url,
    required this.tree,
    required this.truncated,
  });

  factory RepoTree.fromJson(Map<String, dynamic> json) {
    return RepoTree(
      sha: json["sha"],
      url: json["url"],
      // tree: List<RepoInside>.from(
      //     json["tree"].map((x) => RepoInside.fromJson(x))),
      tree: (json['tree'] ?? [])
          .map((x) => RepoInside.fromJson(x))
          .toList()
          .cast<RepoInside>(),
      truncated: json["truncated"],
    );
  }

  Map<String, dynamic> toJson() => {
        "sha": sha,
        "url": url,
        "tree": List<String>.from(tree.map((x) => x.toJson())),
        "truncated": truncated,
      };
}

class RepoInside {
  String path;
  String mode;
  Type type;
  String sha;
  int size;
  String url;

  RepoInside({
    required this.path,
    required this.mode,
    required this.type,
    required this.sha,
    required this.size,
    required this.url,
  });

  factory RepoInside.fromJson(Map<String, dynamic> json) {
    return RepoInside(
      path: json["path"],
      mode: json["mode"],
      type: typeValues.map[json["type"]]!,
      sha: json["sha"],
      size: json["size"] as int,
      url: json["url"],
    );
  }

  Map<String, dynamic> toJson() => {
        "path": path,
        "mode": mode,
        "type": typeValues.reverse[type],
        "sha": sha,
        "size": size,
        "url": url,
      };
}

enum Type { blob, tree }

final typeValues = EnumValues({"blob": Type.blob, "tree": Type.tree});

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;
  }
}

I'm having a really hard time on this subject, I would appreciate it if you could explain your answers in detail. Thanks :)



Solution 1:[1]

In case if size attribute is null here

  factory RepoInside.fromJson(Map<String, dynamic> json) {
    return RepoInside(
      path: json["path"],
      mode: json["mode"],
      type: typeValues.map[json["type"]]!,
      sha: json["sha"],
      size: json["size"] as int,
      url: json["url"],
    );
  }

You can use null-aware oparator ?? to avoid null to get stored in the size field; You can do it like this

  factory RepoInside.fromJson(Map<String, dynamic> json) {
    return RepoInside(
      path: json["path"],
      mode: json["mode"],
      type: typeValues.map[json["type"]]!,
      sha: json["sha"],
      size: json["size"] ?? 0,
      url: json["url"],
    );
  }

What ?? does? Taking examples Example 1

int i;
i = null ?? 7;
print(i); //prints 7

Example 2

int i;
i = 10 ?? 7;
print(i); //prints 10

?? will assign the value at left if it is not null, otherwise the right one.

NOTE: make sure that json["size"] is int! If not then you can use var size; instead of int size;.

Solution 2:[2]

Future<List<RepoInside>> fetchRepoInsideTree() async {
  final response = await http.get(Uri.parse(_link));

  if (response.statusCode == 200) {
    List jsonResponse = json.decode(response.body)['tree']; // ADD
    return jsonResponse.map((e) => RepoInside.fromJson(e)).toList();
  } else {
    throw Exception('Failed to load RepoInside from API');
  }
}

And can be used as in FutureBuilder<List<RepoInside>>()

snapshot.data![i].path()

In short, by adding the ['tree'] expression here, we got the list from the json.

Solution 3:[3]

Try not to specify the version. Just try:

pip3 install numpy

It will install the latest stable version.

You can also try to install it with conda.

If you use conda, you can install NumPy from the defaults or conda-forge channels:

Best practice, use an environment rather than install in the base env

conda create -n my-env conda activate my-env

If you want to install from conda-forge

conda config --env --add channels conda-forge

The actual install command

conda install numpy

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ankit Kumar Maurya
Solution 2 muazzez
Solution 3