用于空值的空检查运算符相关的导致错误的小部件是 FutureBuilder<List<SearchModel>>

Null check operator used on a null value The relevant error-causing widget was FutureBuilder<List<SearchModel>>

我正在搜索 api。但是我有错误说 null 运算符用于 null 值。我尝试了所有可能的方法。但看起来我没能解决问题。 这是我的 api: https://www.moharaj.com.bd/_public/search/products/hoodie

这是我的 json 数据模型:

class SearchModel {
  int? id;
  String? name;
  int? merchantId;
  int? categoryId;
  int? subCategoryId;
  Null? brandId;
  Null? subSubCategoryId;
  int? productCode;
  String? shopSku;
  String? slug;
  int? stock;
  String? salePrice;
  int? discount;
  String? price;
  int? alertQuantity;
  String? purchasePrice;
  String? status;
  int? productPlacement;
  int? productPosition;
  Null? campaignId;
  String? details;
  String? thumnail;
  String? discountType;
  String? createdAt;
  String? updatedAt;
  List<ProductImage>? productImage;

  SearchModel(
      {this.id,
      this.name,
      this.merchantId,
      this.categoryId,
      this.subCategoryId,
      this.brandId,
      this.subSubCategoryId,
      this.productCode,
      this.shopSku,
      this.slug,
      this.stock,
      this.salePrice,
      this.discount,
      this.price,
      this.alertQuantity,
      this.purchasePrice,
      this.status,
      this.productPlacement,
      this.productPosition,
      this.campaignId,
      this.details,
      this.thumnail,
      this.discountType,
      this.createdAt,
      this.updatedAt,
      this.productImage});

  SearchModel.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    merchantId = json['merchant_id'];
    categoryId = json['category_id'];
    subCategoryId = json['sub_category_id'];
    brandId = json['brand_id'];
    subSubCategoryId = json['sub_sub_category_id'];
    productCode = json['product_code'];
    shopSku = json['shop_sku'];
    slug = json['slug'];
    stock = json['stock'];
    salePrice = json['sale_price'];
    discount = json['discount'];
    price = json['price'];
    alertQuantity = json['alert_quantity'];
    purchasePrice = json['purchase_price'];
    status = json['status'];
    productPlacement = json['product_placement'];
    productPosition = json['product_position'];
    campaignId = json['campaign_id'];
    details = json['details'];
    thumnail = json['thumnail'];
    discountType = json['discount_type'];
    createdAt = json['created_at'];
    updatedAt = json['updated_at'];
    if (json['product_image'] != null) {
      productImage = <ProductImage>[];
      json['product_image'].forEach((v) {
        productImage!.add(new ProductImage.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['merchant_id'] = this.merchantId;
    data['category_id'] = this.categoryId;
    data['sub_category_id'] = this.subCategoryId;
    data['brand_id'] = this.brandId;
    data['sub_sub_category_id'] = this.subSubCategoryId;
    data['product_code'] = this.productCode;
    data['shop_sku'] = this.shopSku;
    data['slug'] = this.slug;
    data['stock'] = this.stock;
    data['sale_price'] = this.salePrice;
    data['discount'] = this.discount;
    data['price'] = this.price;
    data['alert_quantity'] = this.alertQuantity;
    data['purchase_price'] = this.purchasePrice;
    data['status'] = this.status;
    data['product_placement'] = this.productPlacement;
    data['product_position'] = this.productPosition;
    data['campaign_id'] = this.campaignId;
    data['details'] = this.details;
    data['thumnail'] = this.thumnail;
    data['discount_type'] = this.discountType;
    data['created_at'] = this.createdAt;
    data['updated_at'] = this.updatedAt;
    if (this.productImage != null) {
      data['product_image'] =
          this.productImage!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class ProductImage {
  int? id;
  int? productId;
  String? productImage;
  String? createdAt;
  String? prefixUrl;
  String? updatedAt;

  ProductImage(
      {this.id,
      this.productId,
      this.productImage,
      this.createdAt,
      this.prefixUrl,
      this.updatedAt});

  ProductImage.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    productId = json['product_id'];
    productImage = json['product_image'];
    createdAt = json['created_at'];
    prefixUrl = json['prefix_url'];
    updatedAt = json['updated_at'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['product_id'] = this.productId;
    data['product_image'] = this.productImage;
    data['created_at'] = this.createdAt;
    data['prefix_url'] = this.prefixUrl;
    data['updated_at'] = this.updatedAt;
    return data;
  }
}

这是json服务代码:

import 'dart:convert';

import 'package:practice_search_app/SearchModel.dart';
import 'package:http/http.dart' as http;

class SearchService {
  static Future<List<SearchModel>> getData() async {
    final response = await http.get(Uri.parse(
        "https://www.moharaj.com.bd/_public/search/products/samsung"));
    print(response.body);
    var model;

    if (response.statusCode == 200 && response.statusCode == 201) {
      print(response.body);
      List decode = json.decode(response.body);

      model = decode.map((e) => SearchModel.fromJson(e)).toList();

      return model;
    } else {
      return model;
    }
  }
}

这是我的浏览页面:

import 'package:flutter/material.dart';
import 'package:practice_search_app/SearchModel.dart';
import 'package:practice_search_app/SearchService.dart';

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

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

class _SearchResultState extends State<SearchResult> {
  late Future<List<SearchModel>> getData;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    getData = SearchService.getData();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
      body: FutureBuilder<List<SearchModel>>(
        future: getData,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return ListView.builder(
                itemCount: snapshot.data!.length,
                itemBuilder: (context, index) {
                  var data = snapshot.data![index];
                  return ListTile(
                    title: Text(data.name.toString()),
                    subtitle: Text(data.details.toString()),
                  );
                });
          } else {
            return const Center(child: CircularProgressIndicator.adaptive());
          }
        },
      ),
    ));
  }
}

in getData Function you written (response.statusCode == 200 && response.statusCode == 201) the && is wrong and should be replaced with || or operation. 试试这个:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class SearchModel {
  int? id;
  String? name;
  int? merchantId;
  int? categoryId;
  int? subCategoryId;
  int? brandId;
  Null? subSubCategoryId;
  int? productCode;
  String? shopSku;
  String? slug;
  int? stock;
  String? salePrice;
  int? discount;
  String? price;
  int? alertQuantity;
  String? purchasePrice;
  String? status;
  int? productPlacement;
  int? productPosition;
  Null? campaignId;
  String? details;
  String? thumnail;
  String? discountType;
  String? createdAt;
  String? updatedAt;
  List<ProductImage>? productImage;

  SearchModel(
      {this.id,
      this.name,
      this.merchantId,
      this.categoryId,
      this.subCategoryId,
      this.brandId,
      this.subSubCategoryId,
      this.productCode,
      this.shopSku,
      this.slug,
      this.stock,
      this.salePrice,
      this.discount,
      this.price,
      this.alertQuantity,
      this.purchasePrice,
      this.status,
      this.productPlacement,
      this.productPosition,
      this.campaignId,
      this.details,
      this.thumnail,
      this.discountType,
      this.createdAt,
      this.updatedAt,
      this.productImage});

  SearchModel.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    merchantId = json['merchant_id'];
    categoryId = json['category_id'];
    subCategoryId = json['sub_category_id'];
    brandId = json['brand_id'];
    subSubCategoryId = json['sub_sub_category_id'];
    productCode = json['product_code'];
    shopSku = json['shop_sku'];
    slug = json['slug'];
    stock = json['stock'];
    salePrice = json['sale_price'];
    discount = json['discount'];
    price = json['price'];
    alertQuantity = json['alert_quantity'];
    purchasePrice = json['purchase_price'];
    status = json['status'];
    productPlacement = json['product_placement'];
    productPosition = json['product_position'];
    campaignId = json['campaign_id'];
    details = json['details'];
    thumnail = json['thumnail'];
    discountType = json['discount_type'];
    createdAt = json['created_at'];
    updatedAt = json['updated_at'];
    if (json['product_image'] != null) {
      productImage = <ProductImage>[];
      json['product_image'].forEach((v) {
        productImage!.add(new ProductImage.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['merchant_id'] = this.merchantId;
    data['category_id'] = this.categoryId;
    data['sub_category_id'] = this.subCategoryId;
    data['brand_id'] = this.brandId;
    data['sub_sub_category_id'] = this.subSubCategoryId;
    data['product_code'] = this.productCode;
    data['shop_sku'] = this.shopSku;
    data['slug'] = this.slug;
    data['stock'] = this.stock;
    data['sale_price'] = this.salePrice;
    data['discount'] = this.discount;
    data['price'] = this.price;
    data['alert_quantity'] = this.alertQuantity;
    data['purchase_price'] = this.purchasePrice;
    data['status'] = this.status;
    data['product_placement'] = this.productPlacement;
    data['product_position'] = this.productPosition;
    data['campaign_id'] = this.campaignId;
    data['details'] = this.details;
    data['thumnail'] = this.thumnail;
    data['discount_type'] = this.discountType;
    data['created_at'] = this.createdAt;
    data['updated_at'] = this.updatedAt;
    if (this.productImage != null) {
      data['product_image'] =
          this.productImage!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class ProductImage {
  int? id;
  int? productId;
  String? productImage;
  String? createdAt;
  String? prefixUrl;
  String? updatedAt;

  ProductImage(
      {this.id,
      this.productId,
      this.productImage,
      this.createdAt,
      this.prefixUrl,
      this.updatedAt});

  ProductImage.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    productId = json['product_id'];
    productImage = json['product_image'];
    createdAt = json['created_at'];
    prefixUrl = json['prefix_url'];
    updatedAt = json['updated_at'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['product_id'] = this.productId;
    data['product_image'] = this.productImage;
    data['created_at'] = this.createdAt;
    data['prefix_url'] = this.prefixUrl;
    data['updated_at'] = this.updatedAt;
    return data;
  }
}

class SearchService {
  static Future<List<SearchModel>> getData() async {
    final response = await http.get(Uri.parse(
        "https://www.moharaj.com.bd/_public/search/products/samsung"));

    if (response.statusCode == 200 || response.statusCode == 201) {
      List decode = json.decode(response.body);

      final model = decode.map((e) => SearchModel.fromJson(e)).toList();

      return model;
    } else {
      return [];
    }
  }
}

void main() {
  runApp(MaterialApp(
    home: SearchResult(),
  ));
}

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

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

class _SearchResultState extends State<SearchResult> {
  late Future<List<SearchModel>> getData;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    getData = SearchService.getData();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
      body: FutureBuilder<List<SearchModel>>(
        future: getData,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return ListView.builder(
                itemCount: snapshot.data!.length,
                itemBuilder: (context, index) {
                  var data = snapshot.data![index];
                  return ListTile(
                    title: Text(data.name.toString()),
                    subtitle: Text(data.details.toString()),
                  );
                });
          } else {
            return const Center(child: CircularProgressIndicator.adaptive());
          }
        },
      ),
    ));
  }
}

在您的 Json 服务页面中:

import 'dart:convert';

import 'package:practice_search_app/SearchModel.dart';
import 'package:http/http.dart' as http;

class SearchService {
  static Future<List<SearchModel>> getData() async {
    final response = await http.get(Uri.parse(
        "https://www.moharaj.com.bd/_public/search/products/samsung"));
    print(response.body);
    var model;

    if (response.statusCode == 200 && response.statusCode == 201) {
      print(response.body);
      List decode = json.decode(response.body);
// Here you parse json file in to your model.......So see instruction
      model = decode.map((e) => SearchModel.fromJson(e)).toList();

      return model;
    } else {
      return model;
    }
  }
}

说明: 1.In ProductImage.fromJson file you parse Map data so data cannot be null 所以请仔细检查后端哪些数据为null.. 2. 然后使用三元运算符检查空值,然后在 Json Model...

中分配任何空值