Flutter报错:Null不是String子类型的问题解决求助
解决Flutter中"type 'Null' is not a subtype of type 'String'"错误
错误日志
E/flutter ( 5602): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'String' E/flutter ( 5602): #0 new Data.fromJson package:siakad_masoem_university/models/transkrip_nilai.dart:188 E/flutter ( 5602): #1 new NilaiMahasiswa.fromJson.<anonymous closure> package:siakad_masoem_university/models/transkrip_nilai.dart:120 E/flutter ( 5602): #2 List.forEach (dart:core-patch/growable_array.dart:416:8) E/flutter ( 5602): #3 new NilaiMahasiswa.fromJson package:siakad_masoem_university/models/transkrip_nilai.dart:119 E/flutter ( 5602): #4 Services.getNilaiMahasiswa package:siakad_masoem_university/provider/services.dart:128 E/flutter ( 5602): <asynchronous suspension> E/flutter ( 5602): #5 _NilaiMahasiswaPageState.fetchData package:siakad_masoem_university/…/akademik/transkrip_nilai.dart:62 E/flutter ( 5602): <asynchronous suspension>
该错误在修改求和代码后触发,以下是相关代码片段:
修改后的求和代码
int getSum() { final uts = data.first.nilaiIndeksUts; final akhir = data.first.nilaiIndeksAkhir; // int? uts = int.tryParse(data.first.nilaiIndeksUts ?? ''); // int? akhir = int.tryParse(data.first.nilaiIndeksAkhir ?? ''); return (uts ?? 0) + (akhir ?? 0); }
数据加载代码
fetchData(int smt) async { final apiResponse = await Services().getNilaiMahasiswa(smt); setState(() { data = (apiResponse.data!); }); }
结果展示代码
Text( getSum().toString(), style: bold6, ),
API调用代码
Future<NilaiMahasiswa> getNilaiMahasiswa(int semester) async { String url = Constant.baseURL; String token = await UtilSharedPreferences.getToken(); final response = await http.get( Uri.parse( '$url/auth/mhs_siakad/transkrip_nilai?semester=$semester', ), headers: { 'Authorization': 'Bearer $token', }, ); print(response.statusCode); print(response.body); if (response.statusCode == 200) { return NilaiMahasiswa.fromJson(jsonDecode(response.body)); } else { throw Exception(); } }
Dart模型代码
class NilaiMahasiswa { String? status; String? code; List<Data>? data; NilaiMahasiswa({this.status, this.code, this.data}); NilaiMahasiswa.fromJson(Map<String, dynamic> json) { status = json['status']; code = json['code']; if (json['data'] != null) { data = <Data>[]; json['data'].forEach((v) { data!.add(Data.fromJson(v)); }); } } Map<String, dynamic> toJson() { final Map<String, dynamic> data = <String, dynamic>{}; data['status'] = status; data['code'] = code; if (this.data != null) { data['data'] = this.data!.map((v) => v.toJson()).toList(); } return data; } } class Data { String? idTranskripNilai; String? idMk; String? kodeMk; String? nmMk; int? sks; int? smt; String? nilaiAkhirUts; String? nilaiHurufUts; int? nilaiIndeksUts; // convert it to int the moment you receive the data String? nilaiAkhirUas; String? nilaiAkhir; String? nilaiHurufAkhir; int? nilaiIndeksAkhir; // convert it to int the moment you receive thedata int? statusNilaiAkhir; int? statusNilaiUts; String? updatedBy; int? summationResult; Data( {this.idTranskripNilai, this.idMk, this.kodeMk, this.nmMk, this.sks, this.smt, this.nilaiAkhirUts, this.nilaiHurufUts, this.nilaiIndeksUts, this.nilaiAkhirUas, this.nilaiAkhir, this.nilaiHurufAkhir, this.nilaiIndeksAkhir, this.statusNilaiAkhir, this.statusNilaiUts, this.updatedBy}); Data.fromJson(Map<String, dynamic> json) { idTranskripNilai = json['id_transkrip_nilai']; idMk = json['id_mk']; kodeMk = json['kode_mk']; nmMk = json['nm_mk']; sks = json['sks']; smt = json['smt']; nilaiAkhirUts = json['nilai_akhir_uts']; nilaiHurufUts = json['nilai_huruf_uts']; // converting to int nilaiIndeksUts = int.tryParse(json['nilai_indeks_uts']); nilaiAkhirUas = json['nilai_akhir_uas']; nilaiAkhir = json['nilai_akhir']; nilaiHurufAkhir = json['nilai_huruf_akhir']; // converting to int nilaiIndeksAkhir = int.tryParse(json['nilai_indeks_akhir']); statusNilaiAkhir = json['status_nilai_akhir']; statusNilaiUts = json['status_nilai_uts']; updatedBy = json['updated_by']; summationResult = nilaiIndeksAkhir! + nilaiIndeksUts!; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = <String, dynamic>{}; data['id_transkrip_nilai'] = this.idTranskripNilai; data['id_mk'] = this.idMk; data['kode_mk'] = this.kodeMk; data['nm_mk'] = this.nmMk; data['sks'] = this.sks; data['smt'] = this.smt; data['nilai_akhir_uts'] = this.nilaiAkhirUts; data['nilai_huruf_uts'] = this.nilaiHurufUts; data['nilai_indeks_uts'] = this.nilaiIndeksUts; data['nilai_akhir_uas'] = this.nilaiAkhirUas; data['nilai_akhir'] = this.nilaiAkhir; data['nilai_huruf_akhir'] = this.nilaiHurufAkhir; data['nilai_indeks_akhir'] = this.nilaiIndeksAkhir; data['status_nilai_akhir'] = this.statusNilaiAkhir; data['status_nilai_uts'] = this.statusNilaiUts; data['updated_by'] = this.updatedBy; return data; } }
错误原因
错误指向Data.fromJson的类型转换逻辑:
int.tryParse要求参数为String类型,但API返回的nilai_indeks_uts/nilai_indeks_akhir可能是null、数字类型(int),导致类型不匹配。summationResult = nilaiIndeksAkhir! + nilaiIndeksUts!使用强制解包,若字段为null会触发空指针。
解决步骤
1. 安全处理类型转换
修改Data.fromJson中的类型转换代码,兼容String、int、null三种情况:
// 处理nilai_indeks_uts final utsIndeks = json['nilai_indeks_uts']; nilaiIndeksUts = utsIndeks is String ? int.tryParse(utsIndeks) ?? 0 : (utsIndeks is int ? utsIndeks : 0); // 处理nilai_indeks_akhir final akhirIndeks = json['nilai_indeks_akhir']; nilaiIndeksAkhir = akhirIndeks is String ? int.tryParse(akhirIndeks) ?? 0 : (akhirIndeks is int ? akhirIndeks : 0);
2. 移除强制解包,处理null值
修改summationResult的赋值逻辑:
summationResult = (nilaiIndeksAkhir ?? 0) + (nilaiIndeksUts ?? 0);
3. 数据加载时的安全判断
避免强制解包apiResponse.data,为空时赋值空列表:
fetchData(int smt) async { final apiResponse = await Services().getNilaiMahasiswa(smt); setState(() { data = apiResponse.data ?? []; }); }
4. 求和函数的空列表判断
防止data.first在空列表时报错:
int getSum() { if (data.isEmpty) return 0; final uts = data.first.nilaiIndeksUts; final akhir = data.first.nilaiIndeksAkhir; return (uts ?? 0) + (akhir ?? 0); }
内容的提问来源于stack exchange,提问作者sharon
相关产品推荐
相关产品推荐

