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 :)
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.