类型列表动态不是类型映射字符串动态的子类型

Posted

技术标签:

【中文标题】类型列表动态不是类型映射字符串动态的子类型【英文标题】:type list dynamic is not a subtype of type map string dynamic 【发布时间】:2021-09-29 18:55:48 【问题描述】:

This is show type list dynamic is not a subtype of type map string dynamic" Now 当我运行模拟器时,在我的模拟器上显示“”我该如何解决?

现在我想创建关于从我的模拟器中查找 api id 的程序,当我输入一些数字并单击按钮时,我会使用文本字段和按钮显示该 ID 的数据或标题,但我只是初学者,所以如果有人喜欢我代码是否正确或者您有一些推荐请告诉我My JSON

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

Future<Album> fetchAlbum() async 
  final response =
  await http.get(Uri.parse('http://192.168.176.131:3000/api/courses/'));

  if (response.statusCode == 200) 
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Album.fromJson(jsonDecode(response.body));

   else 
    // If the server did not return a 200 OK response,
    // then throw an exception1
    throw Exception('Failed to load album');
  


class Album 
  final int userId;
  final int id;
  final String title;

  Album(
    required this.userId,
    required this.id,
    required this.title,
  );

  factory Album.fromJson(Map<String, dynamic> json) 
    return Album(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
    );
  


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

class MyApp extends StatefulWidget 
  MyApp(Key? key) : super(key: key);


  @override
  _MyAppState createState() => _MyAppState();


class _MyAppState extends State<MyApp> 
  late Future<Album> futureAlbum;

  @override
  void initState() 
    super.initState();
    futureAlbum = fetchAlbum();
  

  Widget build(BuildContext context) 
    TextEditingController searchController = new TextEditingController();
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
          appBar: AppBar(
            title: Text('Fetch Data Example'),
          ),

          body: Column(children: [
            Container(
                child: Row(children: [
                  Expanded(
                      flex: 2,
                      child: TextField(
                          controller: searchController
                      )
                  ),
                  Expanded(
                      flex: 1,
                      child: FlatButton(
                        onPressed: () 
                          print(
                              "this is the text to search for => $searchController
                                  .text");
                        ,
                        child: Text("Search"),
                      )
                  )
                ],)
            ),
            Center(
              child: FutureBuilder<Album>(
                future: futureAlbum,
                builder: (context, snapshot) 
                  if (snapshot.hasData) 
                    return Text(snapshot.data!.title);
                   else if (snapshot.hasError) 
                    return Text("$snapshot.error");
                  
                  // By default, show a loading spinner.
                  return CircularProgressIndicator();
                ,
              ),
            ),
          ],)

      ),
    );
  

JSON 代码

const Joi = require('joi');
const express = require('express');
const app = express();

app.use(express.json());

const courses = [
     userId:1, id:1, title:'course 1',
     userId:2, id:2, title:'course 2',
     userId:3, id:3, title:'course 3',
]; 

app.get('/', (req,res)  => 
    res.send('Hello world');

);

app.get('/api/courses',(req, res) => 
    res.send(courses);
);

app.post('/api/courses', (req, res) =>    
    const  error   = validateCourse(req.body);
    if (error)return res.status(400).send(error.details[0].message);


    const course = 
        id: courses.length +1,
        name: req.body.name
    ;
    courses.push(course);
    res.send(course);
);

app.put('/api/courses/:id', (req, res) => 
    const course = courses.find(c => c.id === parseInt(req.params.id));
    if (!course) return res.status(404).send('The course with the given ID was not found.');

    const error = validateCourse(req.body); //result.eror
    if (error) return res.status(400).send(error.details[0].message);
        
    
    //Update course
    course.name = req.body.name;
    res.send(course);
    //Return the updated course

);



app.delete('/api/courses/:id', (req, res) => 
    const course = courses.find(c => c.id === parseInt(req.params.id));
    if (!course) return res.status(404).send('The course with the given ID was not found.');

    const index = courses.indexOf(course);
    courses.splice(index, 1);
    res.send(course);
);
function validateCourse(course)
    const schema = 
        name: Joi.string().min(3).required()
    ;

    return Joi.validate(course, schema);

app.get('/api/courses/:id', (req, res) => 常量课程 = course.find(c => c.id === parseInt(req.params.id)); if (!course) return res.status(404).send('没有找到给定 ID 的课程。'); res.send(课程); );

常量端口 = process.env.PORT || 3000; //app.listen(port, () => console.log(Listening on port $port ..)); app.listen(3000, '0.0.0.0');

【问题讨论】:

具体错误在哪里,请分享错误截图或日志,帮助我们更好地理解问题。 你能提供你的json响应吗? 你能告诉我们你的 response.body 和你的 fromJson 构造函数吗,问题可能就在那里。 我编辑我给你截图你能看到吗?并发布我的 Json 代码 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange 网络上发帖,您已在 CC BY-SA 4.0 license 下授予 Stack Exchange 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 Stack Exchange 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请参阅:How does deleting work? 【参考方案1】:

您应该将 jsonDecode 的返回值转换为 Map &lt;String, dynamic&gt;。 jsonDecode 返回 dynamic 值,而不是 Album.fromJson 期望的 Map &lt;String, dynamic&gt;

【讨论】:

工厂 Album.fromJson(Map json) 更改为工厂 Album.fromJson(dyanmic) ?像这样? 不,转换 jsonDecode 返回值可以这样完成: Album.fromJson(jsonDecode(response.body) as Map );您还可以在之前验证动态返回值是否可以使用 is 关键字进行强制转换。

以上是关于类型列表动态不是类型映射字符串动态的子类型的主要内容,如果未能解决你的问题,请参考以下文章

具有动态类型元素的对象列表

Spring Boot 嵌套动态 json 请求映射到 pojo

如何解析类型“时间戳”不是类型转换中“字符串”类型的子类型

类型“List<dynamic>”不是“Map<String”类型的子类型,在颤振应用中是动态的

如何从字符串列表中的名称和类型动态创建 DataTable 列? [复制]

elasticsearch的字符串动态映射