首页 > 解决方案 > 如何在flutter中解析复杂的json数据并分配给模型?

问题描述

这是我用来从 api 获取数据然后将它们分配给模型的方法。

    var headers = {
      'API-Key': 'TEST_f+y9/tHG+yVxEq3uS3H1ogfezHSCWSq5MsIXUOnIV+Q',
      'Content-Type': 'application/json',
    };
    var data = '"shipment": {
    "validate_address": "no_validation",
    "ship_to": {
      "name": "Amanda Miller",
      "phone": "555-555-5555",
      "address_line1": "525 S Winchester Blvd",
      "city_locality": "San Jose",
      "state_province": "CA",
      "postal_code": "95128",
      "country_code": "US",
      "address_residential_indicator": "yes"
    },
    "ship_from": {
      "company_name": "Example Corp.",
      "name": "John Doe",
      "phone": "111-111-1111",
      "address_line1": "4009 Marathon Blvd",
      "address_line2": "Suite 300",
      "city_locality": "Austin",
      "state_province": "TX",
      "postal_code": "78756",
      "country_code": "US",
      "address_residential_indicator": "no"
    },
    "packages": [
      {
        "weight": {
          "value": 1.0,
          "unit": "ounce"
        }
      }
    ]
  }
}';

    final response = await http.post('https://api.shipengine.com/v1/rates', headers: headers, body: data);

    if (response.statusCode == 200) {
      String responseBody = response.body;
      var data = json.decode(responseBody);
      print(data);
        print(data["rate_response"]["rates"]);
      ResRate rates = new ResRate.fromJson(data);
      print(rates.rates[0].amount);
    } else {
      print(response.statusCode);
      print(response.body);
    }
  }

是model.dart


 // Amount amount;
  List<Rates> rates;

  ResRate({
   // this.amount,
    this.rates});

  factory ResRate.fromJson(Map<String, dynamic> parsedJson){

    var list = parsedJson['rates'] as List;
    List<Rates> rates = list.map((i) => Rates.fromJson(i)).toList();


    return ResRate(

     //   amount: Amount.fromJson(parsedJson['amount']),
        rates: rates

    );
  }
}



class Amount{
  var currency;
  String amount;

  Amount({this.currency,
    this.amount});

  factory Amount.fromJson(Map<String, dynamic> parsedJson){
    return Amount(
      currency: parsedJson['currency'],
      amount : parsedJson['amount'],
    );
  }

}

class Rates{
  var rate_id;
  var rate_type;
   var carrier_id;
  Amount amount;

  //List<Amount> shipping_amount;

  Rates({
    this.rate_id, this.amount,
      this.rate_type, this.carrier_id,

  });

  factory Rates.fromJson(Map<String, dynamic> parsedJson){

  //  var list = parsedJson['images'] as List;
   // List<Image> images = list.map((i) => Image.fromJson(i)).toList();


    return Rates(
        rate_id: parsedJson['rate_id'],
      rate_type: parsedJson['rate_type'],
      carrier_id: parsedJson['carrier_id'],

      amount: Amount.fromJson(parsedJson['shipping_amount']),
    );
  }
}

但是我在控制台中遇到了这样的错误。

未处理的异常:NoSuchMethodError:在 null 上调用了方法“map”,它指向下面的模型代码


    var list = parsedJson['rates'] as List;
    List<Rates> rates = list.map((i) => Rates.fromJson(i)).toList();

我尝试打印响应正文,成功获取响应正文并在控制台中打印。对象速率也在响应中获取。但显示为空。由于此响应是一个复杂的响应,因此费率也有对象。这是从 api 获取的响应。

  "rate_response": {
    "rate_request_id": 501834,
    "shipment_id": "se-2127183",
    "status": "completed",
    "created_at": "2019-07-26T22:10:50.286Z",
    "rates": [
      {
        "rate_id": "se-11744390",
        "rate_type": "shipment",
        "carrier_id": "se-123890",
        "shipping_amount": {
          "currency": "usd",
          "amount": 9.37
        },
        "insurance_amount": {
          "currency": "usd",
          "amount": 0.00
        },
        "confirmation_amount": {
          "currency": "usd",
          "amount": 0.00
        },
        "other_amount": {
          "currency": "usd",
          "amount": 0.00
        },
        "delivery_days": 3,
        "guaranteed_service": false,
        "estimated_delivery_date": "2019-07-26T05:00:00.000Z",
        "carrier_delivery_days": "Friday by 11:00 PM",
        "ship_date": "2019-07-26T05:00:00.000Z",
        "negotiated_rate": false,
        "service_type": "UPS® Ground",
        "service_code": "ups_ground",
        "trackable": true,
        "validation_status": "valid",
        "warning_messages": [],
        "error_messages": [],
        "carrier_code": "ups",
        "carrier_nickname": "UPS-28A1R9",
        "carrier_friendly_name": "UPS"
      }
    ],
    "invalid_rates": []
  },
  "shipment_id": "se-2127183",
  "carrier_id": "",
  "external_shipment_id": null,
  "ship_date": "2019-07-26T05:00:00.000Z",
  "created_at": "2019-07-26T22:10:50.286Z",
  "modified_at": "2019-07-26T22:10:50.286Z",
  "shipment_status": "pending",
  "ship_to": {
    "name": "Amanda Miller",
    "phone": "555-555-5555",
    "address_line1": "525 S Winchester Blvd",
    "city_locality": "San Jose",
    "state_province": "CA",
    "postal_code": "95128",
    "country_code": "US",
    "address_residential_indicator": "yes"
  },
  "ship_from": {
    "company_name": "Example Corp.",
    "name": "John Doe",
    "phone": "111-111-1111",
    "address_line1": "4009 Marathon Blvd",
    "address_line2": "Suite 300",
    "city_locality": "Austin",
    "state_province": "TX",
    "postal_code": "78756",
    "country_code": "US",
    "address_residential_indicator": "no"
  },
  "return_to": {
    "company_name": "Example Corp.",
    "name": "John Doe",
    "phone": "111-111-1111",
    "address_line1": "4009 Marathon Blvd",
    "address_line2": "Suite 300",
    "city_locality": "Austin",
    "state_province": "TX",
    "postal_code": "78756",
    "country_code": "US",
    "address_residential_indicator": "no"
  },
  "confirmation": "none",
  "advanced_options": {
    "bill_to_account": null,
    "bill_to_country_code": null,
    "bill_to_party": null,
    "bill_to_postal_code": null,
    "contains_alcohol": false,
    "custom_field1": null,
    "custom_field2": null,
    "custom_field3": null,
    "non_machinable": false,
    "saturday_delivery": false
  },
  "insurance_provider": "none",
  "tags": [],
  "total_weight": {
    "value": 1.00,
    "unit": "ounce"
  },
  "packages": [
    {
      "weight": {
        "value": 1.00,
        "unit": "ounce"
      },
      "dimensions": {
        "unit": "inch",
        "length": 0.0,
        "width": 0.0,
        "height": 0.0
      },
      "insured_value": {
        "currency": "usd",
        "amount": 0.0
      }
    }
  ]
}


标签: jsonflutterapidart

解决方案


我自己找到了一个修复方法,结果我需要在模型中映射时从数组中添加子列表和对象头。

\\replace this 
    var list = parsedJson['rates'] as List;
\\with this
    var list = parsedJson["rate_response"]['rates'] as List;

    List<Rates> rates = list.map((i) => Rates.fromJson(i)).toList();

推荐阅读