类型'List <Map <String,String >>'不是类型转换中类型'String'的子类型

时间:2019-11-07 07:07:03

标签: flutter dart

我正在处理项目,并且在发布请求时遇到错误,当我使用邮递员时,它工作正常,但是当我使用Flutter时,它给了我type 'List<Map<String, String>>' is not a subtype of type 'String' in type cast异常提示

  • 请求使用嵌套列表。

邮递员的身体和反应: (https://i.imgur.com/HS5Y6CA.png

Flutter代码:

try {
    http.Response response = await http.post(Uri.parse(url),
        headers: {
            "Accept": "application/json",
            'authorization' : 'Bearer ${tokenValue}',
        },
        body: {
            "date": "2019-12-30",
            "studentId": "1",
            "amount": "10",
            "numberOfItems": "2",
            "mqsfId": "1",
            "items": [{
                "itemCount": "1",
                "productId": "1",
                "productName": "Apple juice",
                "productPrice": "8"
            }, {
                "itemCount": "1",
                "productId": "2",
                "productName": "Sandwish",
                "productPrice": "2"
            }]
    });

    resBody = json.decode(response.body);
    if (response.statusCode == 201) {
        // Some Actions
    } else {
        // Some Actions
    }
} catch(e) {
    print(e);
}

此代码返回我异常消息:type 'List<Map<String, String>>' is not a sub type of type 'String' in type cast

当我将嵌套列表转换为String时:

"items":[{
    "itemCount": "1",
    "productId": "1",
    "productName": "Apple juice",
    "productPrice": "8"
}, {
   "itemCount": "1",
   "productId": "2",
   "productName": "Sandwish",
   "productPrice": "2"
}].toString()

它发送请求并以StatusCode 500返回服务器错误,但是当我检查数据库时记录了订单,但是nested array is empty !!

记录的数据示例(服务器错误请求的输出):

date: 2019-12-30,
studentId: 1,
amount: 10,
numberOfItems: 2,
mqsfId: 1,
items:[]
// item shouldn't be empty

2 个答案:

答案 0 :(得分:0)

您可以使用以下

构造和使用body
   var response = await http.post(url, body: payload);

代码片段以使用json字符串或对象创建有效负载

    payload = payloadFromJson(jsonString);
    print('item 0 product name ${payload.items[0].productName}');

    Item item1 = Item(itemCount: "1", productName: "abc");
    Item item2 = Item(itemCount: "2", productName: "def");
    List<Item> itemList = [];
    itemList.add(item1);
    itemList.add(item2);
    Payload payload1 = Payload(date: DateTime.parse("2019-12-30"), items: itemList );
    print('item 0 product name ${payload1.items[0].productName}');

相关课程

// To parse this JSON data, do
//
//     final payload = payloadFromJson(jsonString);

import 'dart:convert';

Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));

String payloadToJson(Payload data) => json.encode(data.toJson());

class Payload {
    DateTime date;
    String studentId;
    String amount;
    String numberOfItems;
    String mqsfId;
    List<Item> items;

    Payload({
        this.date,
        this.studentId,
        this.amount,
        this.numberOfItems,
        this.mqsfId,
        this.items,
    });

    factory Payload.fromJson(Map<String, dynamic> json) => Payload(
        date: DateTime.parse(json["date"]),
        studentId: json["studentId"],
        amount: json["amount"],
        numberOfItems: json["numberOfItems"],
        mqsfId: json["mqsfId"],
        items: List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "date": "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
        "studentId": studentId,
        "amount": amount,
        "numberOfItems": numberOfItems,
        "mqsfId": mqsfId,
        "items": List<dynamic>.from(items.map((x) => x.toJson())),
    };
}

class Item {
    String itemCount;
    String productId;
    String productName;
    String productPrice;

    Item({
        this.itemCount,
        this.productId,
        this.productName,
        this.productPrice,
    });

    factory Item.fromJson(Map<String, dynamic> json) => Item(
        itemCount: json["itemCount"],
        productId: json["productId"],
        productName: json["productName"],
        productPrice: json["productPrice"],
    );

    Map<String, dynamic> toJson() => {
        "itemCount": itemCount,
        "productId": productId,
        "productName": productName,
        "productPrice": productPrice,
    };
}

完整代码

import 'package:flutter/material.dart';
// To parse this JSON data, do
//
//     final payload = payloadFromJson(jsonString);

import 'dart:convert';

Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));

String payloadToJson(Payload data) => json.encode(data.toJson());

class Payload {
  DateTime date;
  String studentId;
  String amount;
  String numberOfItems;
  String mqsfId;
  List<Item> items;

  Payload({
    this.date,
    this.studentId,
    this.amount,
    this.numberOfItems,
    this.mqsfId,
    this.items,
  });

  factory Payload.fromJson(Map<String, dynamic> json) => Payload(
    date: DateTime.parse(json["date"]),
    studentId: json["studentId"],
    amount: json["amount"],
    numberOfItems: json["numberOfItems"],
    mqsfId: json["mqsfId"],
    items: List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "date": "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
    "studentId": studentId,
    "amount": amount,
    "numberOfItems": numberOfItems,
    "mqsfId": mqsfId,
    "items": List<dynamic>.from(items.map((x) => x.toJson())),
  };
}

class Item {
  String itemCount;
  String productId;
  String productName;
  String productPrice;

  Item({
    this.itemCount,
    this.productId,
    this.productName,
    this.productPrice,
  });

  factory Item.fromJson(Map<String, dynamic> json) => Item(
    itemCount: json["itemCount"],
    productId: json["productId"],
    productName: json["productName"],
    productPrice: json["productPrice"],
  );

  Map<String, dynamic> toJson() => {
    "itemCount": itemCount,
    "productId": productId,
    "productName": productName,
    "productPrice": productPrice,
  };
}


void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  String jsonString = '''
  {
              "date": "2019-12-30",
              "studentId": "1",
              "amount": "10",
              "numberOfItems": "2",
              "mqsfId": "1",
              "items":[
                {
                  "itemCount": "1",
                  "productId": "1",
                  "productName": "Apple juice",
                  "productPrice": "8"
                },
                {
                  "itemCount": "1",
                  "productId": "2",
                  "productName": "Sandwish",
                  "productPrice": "2"
                }
              ]
            }
  ''';

  Payload payload;


  void _incrementCounter() {
    payload = payloadFromJson(jsonString);
    print('item 0 product name ${payload.items[0].productName}');

    Item item1 = Item(itemCount: "1", productName: "abc");
    Item item2 = Item(itemCount: "2", productName: "def");
    List<Item> itemList = [];
    itemList.add(item1);
    itemList.add(item2);
    Payload payload1 = Payload(date: DateTime.parse("2019-12-30"), items: itemList );
    print('item 0 product name ${payload1.items[0].productName}');


    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug painting" (press "p" in the console, choose the
          // "Toggle Debug Paint" action from the Flutter Inspector in Android
          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
          // to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

输出

I/flutter (32293): item 0 product name Apple juice
I/flutter (32293): item 0 product name abc

答案 1 :(得分:0)

直到我发现这个from the docs为止,这令人困惑:

body sets the body of the request. It can be a String, a List<int> or a Map<String, String>.

仅将字段的值转换为String显然会阻止其解析。

好,让我们尝试一下(基于here):

        http.Response response = await http.post(Uri.parse(url),
            headers: {
              'Content-type' : 'application/json',
              "Accept": "application/json",
              'authorization' : 'Bearer ${tokenValue}',
            },
            body: json.encode({
              "date": "2019-12-30",
              "studentId": "1",
              "amount": "10",
              "numberOfItems": "2",
              "mqsfId": "1",
              "items":[
                {
                  "itemCount": "1",
                  "productId": "1",
                  "productName": "Apple juice",
                  "productPrice": "8"
                },
                {
                  "itemCount": "1",
                  "productId": "2",
                  "productName": "Sandwish",
                  "productPrice": "2"
                }
              ]
            })
        );