Flutter, тип «int» не является подтипом «string», вызывающего rest API

Я новичок во Flutter и dart, но мне было интересно узнать о них, в настоящее время я застрял в попытках получить данные внутри приложения. Я следил за документами Flutter Docs создал файл модели и будущее для вызова API весь код ниже. Я провел некоторое исследование и попробовал пару вещей, но ничего не помогло решить ошибку type 'int' is not a subtype of 'string' это, скорее всего, простая ошибка, но любые указатели приветствуются.

Извините, если какая-либо информация пропущена, я должен был напечатать это в спешке. Дайте мне знать, если что-то еще требуется!

Используемый API: https://valorant-api.com/v1/currencies

API Response
{
    "status": 200,
    "data": [
        {
            "uuid": "85ad13f7-3d1b-5128-9eb2-7cd8ee0b5741",
            "displayName": "VP",
            "displayNameSingular": "VP",
            "displayIcon": "https://media.valorant-api.com/currencies/85ad13f7-3d1b-5128-9eb2-7cd8ee0b5741/displayicon.png",
            "largeIcon": "https://media.valorant-api.com/currencies/85ad13f7-3d1b-5128-9eb2-7cd8ee0b5741/largeicon.png",
            "assetPath": "ShooterGame/Content/Currencies/Currency_AresPoints_DataAsset"
        },
        {
            "uuid": "85ca954a-41f2-ce94-9b45-8ca3dd39a00d",
            "displayName": "Dough",
            "displayNameSingular": "Dough",
            "displayIcon": "https://media.valorant-api.com/currencies/85ca954a-41f2-ce94-9b45-8ca3dd39a00d/displayicon.png",
            "largeIcon": "https://media.valorant-api.com/currencies/85ca954a-41f2-ce94-9b45-8ca3dd39a00d/largeicon.png",
            "assetPath": "ShooterGame/Content/Currencies/Currency_Dough_DataAsset"
        },
        {
            "uuid": "f08d4ae3-939c-4576-ab26-09ce1f23bb37",
            "displayName": "Free Agents",
            "displayNameSingular": "Free Agent",
            "displayIcon": "https://media.valorant-api.com/currencies/f08d4ae3-939c-4576-ab26-09ce1f23bb37/displayicon.png",
            "largeIcon": "https://media.valorant-api.com/currencies/f08d4ae3-939c-4576-ab26-09ce1f23bb37/largeicon.png",
            "assetPath": "ShooterGame/Content/Currencies/Currency_RecruitmentToken_DataAsset"
        },
        {
            "uuid": "e59aa87c-4cbf-517a-5983-6e81511be9b7",
            "displayName": "Radianite Points",
            "displayNameSingular": "Radianite Point",
            "displayIcon": "https://media.valorant-api.com/currencies/e59aa87c-4cbf-517a-5983-6e81511be9b7/displayicon.png",
            "largeIcon": "https://media.valorant-api.com/currencies/e59aa87c-4cbf-517a-5983-6e81511be9b7/largeicon.png",
            "assetPath": "ShooterGame/Content/Currencies/Currency_UpgradeToken_DataAsset"
        }
    ]
}
Model file
class CurrencyModel {
  final String status;
  final int uuid;
  final String displayName;
  final String displayNameSingular;
  final String displayIcon;
  final String largeIcon;
  final String assetPath;

  const CurrencyModel({
    required this.status,
    required this.uuid,
    required this.assetPath,
    required this.displayIcon,
    required this.displayName,
    required this.displayNameSingular,
    required this.largeIcon,
  });

  factory CurrencyModel.fromJson(Map<String, dynamic> json) {
    return CurrencyModel(
      status: json['status'],
      uuid: int.parse(json['data']['uuid']),
      assetPath: json['data']['assestPath'], 
      displayIcon: json['data']['displayIcon'], 
      displayName: json['data']['displayName'], 
      displayNameSingular: json['data']['displayNameSingular'], 
      largeIcon: json['data']['largeIcon'],
    );
  }
}
Data Fetch file
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:valoranttools/models/models.dart';

Future<CurrencyModel> fetchCurrency() async {
  final response =
      await http.get(Uri.parse('https://valorant-api.com/v1/currencies'));

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    print(response.body);
    return CurrencyModel.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');
  }
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
73
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Проблема в вашем Currencymodel вы пытаетесь добавить строку в int

измените эту строку final int uuid; на эту final String uuid;

как упомянул @OMi Shah, вам нужно удалить int.parse и использовать его вот так uuid: json['data']['uuid'],

если у вас проблема с вашим статусом, то вам нужно разобрать его на int вот так int.parse(json['status']),

просто изменение типа не исправит, из-за этого: int.parse(json['data']['uuid']), поэтому вам нужно удалить синтаксический анализ, т.е. uuid: json['data']['uuid'], ...

OMi Shah 09.05.2023 06:05

да, верно (не видел)

MrShakila 09.05.2023 07:21

Огромное спасибо за быстрые ответы, я попробовал это, и, к сожалению, это просто приводит к ошибке, которая у меня была раньше, type 'int' is not a Subtype of type 'String' это как-то связано с тем, что в ответе status есть int?

MatDoak 09.05.2023 15:26

проверьте сейчас, я обновил свой ответ

MrShakila 10.05.2023 05:39

Спасибо, сделаю в ближайшее время, если получится, сообщу

MatDoak 10.05.2023 06:37

бывший:

class CurrencyModel {
  final int? status;
  final List<Data>? data;

  CurrencyModel({
    this.status,
    this.data,
  });

  CurrencyModel.fromJson(Map<String, dynamic> json)
    : status = json['status'] as int?,
      data = (json['data'] as List?)?.map((dynamic e) => Data.fromJson(e as Map<String,dynamic>)).toList();

  Map<String, dynamic> toJson() => {
    'status' : status,
    'data' : data?.map((e) => e.toJson()).toList()
  };
}

class Data {
  final String? uuid;
  final String? displayName;
  final String? displayNameSingular;
  final String? displayIcon;
  final String? largeIcon;
  final String? assetPath;

  Data({
    this.uuid,
    this.displayName,
    this.displayNameSingular,
    this.displayIcon,
    this.largeIcon,
    this.assetPath,
  });

  Data.fromJson(Map<String, dynamic> json)
    : uuid = json['uuid'] as String?,
      displayName = json['displayName'] as String?,
      displayNameSingular = json['displayNameSingular'] as String?,
      displayIcon = json['displayIcon'] as String?,
      largeIcon = json['largeIcon'] as String?,
      assetPath = json['assetPath'] as String?;

  Map<String, dynamic> toJson() => {
    'uuid' : uuid,
    'displayName' : displayName,
    'displayNameSingular' : displayNameSingular,
    'displayIcon' : displayIcon,
    'largeIcon' : largeIcon,
    'assetPath' : assetPath
  };
}

// your code

Map<String, dynamic> json = {
    "status": 200,
    "data": [
      {
        "uuid": "85ad13f7-3d1b-5128-9eb2-7cd8ee0b5741",
        "displayName": "VP",
        "displayNameSingular": "VP",
        "displayIcon":
            "https://media.valorant-api.com/currencies/85ad13f7-3d1b-5128-9eb2-7cd8ee0b5741/displayicon.png",
        "largeIcon":
            "https://media.valorant-api.com/currencies/85ad13f7-3d1b-5128-9eb2-7cd8ee0b5741/largeicon.png",
        "assetPath":
            "ShooterGame/Content/Currencies/Currency_AresPoints_DataAsset"
      },
      {
        "uuid": "85ca954a-41f2-ce94-9b45-8ca3dd39a00d",
        "displayName": "Dough",
        "displayNameSingular": "Dough",
        "displayIcon":
            "https://media.valorant-api.com/currencies/85ca954a-41f2-ce94-9b45-8ca3dd39a00d/displayicon.png",
        "largeIcon":
            "https://media.valorant-api.com/currencies/85ca954a-41f2-ce94-9b45-8ca3dd39a00d/largeicon.png",
        "assetPath": "ShooterGame/Content/Currencies/Currency_Dough_DataAsset"
      }
    ]
  };
    
 CurrencyModel cModel = CurrencyModel.fromJson(
      json); // responseJson (json) - Map<String, dynamic>

  print(cModel.data!.length);


`

Спасибо за ответ, я попробовал этот метод с отдельным классом Data с другими типами в нем, и это приводит к другой ошибке после сопоставления через type list<dynamic> is not a subtype of list<data>?

MatDoak 09.05.2023 15:46

Изменять final int uuid; к final String uuid; в модельном классе


Изменять uuid: int.parse(json['data']['uuid']), к uuid: json['data']['uuid']

потому что вы пытаетесь проанализировать поле «uuid» из ответа API как int

class CurrencyModel {
      final int status;
      final String uuid;
      final String displayName;
      final String displayNameSingular;
      final String displayIcon;
      final String largeIcon;
      final String assetPath;
    
      const CurrencyModel({
        required this.status,
        required this.uuid,
        required this.assetPath,
        required this.displayIcon,
        required this.displayName,
        required this.displayNameSingular,
        required this.largeIcon,
      });
    
      factory CurrencyModel.fromJson(Map<String, dynamic> json) {
        return CurrencyModel(
          status: json['status'],
          uuid: json['data']['uuid'],
          assetPath: json['data']['assetPath'], 
          displayIcon: json['data']['displayIcon'], 
          displayName: json['data']['displayName'], 
          displayNameSingular: json['data']['displayNameSingular'], 
          largeIcon: json['data']['largeIcon'],
        );
      }
    }
Ответ принят как подходящий
// To parse this JSON data, do
//
//     final currencyModel = currencyModelFromJson(jsonString);

import 'dart:convert';

CurrencyModel currencyModelFromJson(String str) => CurrencyModel.fromJson(json.decode(str));

String currencyModelToJson(CurrencyModel data) => json.encode(data.toJson());

class CurrencyModel {
    int status;
    List<Datum> data;

    CurrencyModel({
        required this.status,
        required this.data,
    });

    factory CurrencyModel.fromJson(Map<String, dynamic> json) => CurrencyModel(
        status: json["status"],
        data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "status": status,
        "data": List<dynamic>.from(data.map((x) => x.toJson())),
    };
}

class Datum {
    String uuid;
    String displayName;
    String displayNameSingular;
    String displayIcon;
    String largeIcon;
    String assetPath;

    Datum({
        required this.uuid,
        required this.displayName,
        required this.displayNameSingular,
        required this.displayIcon,
        required this.largeIcon,
        required this.assetPath,
    });

    factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        uuid: json["uuid"],
        displayName: json["displayName"],
        displayNameSingular: json["displayNameSingular"],
        displayIcon: json["displayIcon"],
        largeIcon: json["largeIcon"],
        assetPath: json["assetPath"],
    );

    Map<String, dynamic> toJson() => {
        "uuid": uuid,
        "displayName": displayName,
        "displayNameSingular": displayNameSingular,
        "displayIcon": displayIcon,
        "largeIcon": largeIcon,
        "assetPath": assetPath,
    };
}

Это было лучшее решение и, безусловно, самое быстрое, но оба были отличным уроком, и я уверен, что в будущем у меня будет больше вопросов, все, о чем я прошу, это в следующий раз, возможно, включить немного больше информации в ответ, спасибо!

MatDoak 10.05.2023 07:44

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