Тип 'List<dynamic>' не является подтипом типа 'Map<String, dynamic в приложении флаттера

Я пытаюсь создать запрос API во Flutter, но в ответ получаю следующую ошибку

тип 'List<dynamic>' не является подтипом типа 'Map<String, dynamic>'

Я пытаюсь создать первый API и, пожалуйста, дайте мне знать, подходит ли этот подход.

вот мой код

import 'package:flutter/material.dart';

class Product {
  final int id;
  final String title, description;
  final String images;
  final List<Color> colors;
  final double price;
  final double rating;
  final bool isFavourite, isPopular;

  Product(
      {this.id,
      this.images,
      this.colors,
      this.title,
      this.price,
      this.rating,
      this.description,
      this.isFavourite,
      this.isPopular});
  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'],
      images: json['images'],
      title: json['title'],
      price: json['price'],
      rating: json['rating'],
      description: json['description'],
    );
  }
}


Future<Product> fetchProd() async {
  final response = await http.get('https://test.com/sampleapi.php');

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Product.fromJson(jsonDecode(response.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

class ProdList extends StatefulWidget {
  @override
  _ProdListState createState() => _ProdListState();
}

class _ProdListState extends State<ProdList> {
  Future<Product> futureProdLists;
  @override
  void initState() {
    super.initState();
    futureProdLists = fetchProd();
  
  }

 

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      Padding(
        padding:
            EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)),
        child: SectionTitle(title: "Popular Products", press: () {}),
      ),
      SizedBox(height: getProportionateScreenWidth(20)),
      SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: FutureBuilder<Product>(
          future: futureProdLists,
          builder: (context, snapshot) {
            print(snapshot);
            if (snapshot.hasData) {
              return Text(snapshot.data.title);
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }

Вот мой пример API

[
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  },
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  },
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  },
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  },
  {
    "id": "0001",
    "images": "assets/images/ps4_console_white_1.png",
    "title": "Wireless Controller for PS4",
    "price": 25,
    "description": "description",
    "rating": 4.8,
    "rating (copy)": 4.8,
    "isFavourite": true,
    "isPopular": true
  }
]
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
5 652
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Дело в том, что ваш api ответ дает вам json массив объекта продукта, и вы пытаетесь преобразовать массив в объект продукта, который является проблемой.

Теперь вам нужно перебрать массив json и преобразовать каждый элемент в объект Product и сохранить их в списке.

Замените свой метод fetchProd приведенным ниже фрагментом кода.

Future<List<Product>> fetchProd() async {
  List<Product> prodList = [];

  final response = await http.get('https://test.com/sampleapi.php');

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    var jsonList = jsonDecode(response.body);
    for(var prod in jsonList){
      prodList.add(Product.fromJson(prod));
    }
    return prodList;
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

Значение типа «List<Product>» не может быть возвращено функцией «fetchProd», так как оно имеет возвращаемый тип «Future<Product>».dartreturn_of_invalid_type

vellai durai 13.12.2020 05:46

Поскольку @Saiful Islam, его API возвращает массив JSON, а не объект json, так что это список, а не карта.

Rahul 13.12.2020 05:46

Я обновил код, так что попробуйте прямо сейчас. @веллаи дураи

Saiful Islam 13.12.2020 05:55

попробуй это

Future<Product> fetchProd() async {
  final response = await http.get('https://test.com/sampleapi.php');

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return (response.body as List)
      .map((item) => Product.fromJson(item))
      .toList();
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

Это точно сработает. final Product product = productFromJson(jsonString);


import 'dart:convert';

List<Product> productFromJson(String str) => List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));

String productToJson(List<Product> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Product {
    Product({
        this.id,
        this.images,
        this.title,
        this.price,
        this.description,
        this.rating,
        this.ratingCopy,
        this.isFavourite,
        this.isPopular,
    });

    String id;
    String images;
    String title;
    int price;
    String description;
    double rating;
    double ratingCopy;
    bool isFavourite;
    bool isPopular;

    factory Product.fromJson(Map<String, dynamic> json) => Product(
        id: json["id"],
        images: json["images"],
        title: json["title"],
        price: json["price"],
        description: json["description"],
        rating: json["rating"].toDouble(),
        ratingCopy: json["rating (copy)"].toDouble(),
        isFavourite: json["isFavourite"],
        isPopular: json["isPopular"],
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "images": images,
        "title": title,
        "price": price,
        "description": description,
        "rating": rating,
        "rating (copy)": ratingCopy,
        "isFavourite": isFavourite,
        "isPopular": isPopular,
    };
}

Другие вопросы по теме