тип 'int' не является подтипом типа 'double' - ошибка дротика / флаттера - PullRequest
0 голосов
/ 24 апреля 2020

Итак, у меня есть настроенный API, который возвращает следующий вывод для указанной конечной точки c при вызове:

{
    "total_user_currency": 0.1652169792,
    "total_sats": 2184,
    "total_btc": 0.00002184,
    "outputArray": [
        {
            "txid": "642fd534cb3a670a31f4d59e70452b133b0b461d871db44fcc91d32bb6b6f0cc",
            "vout": 2,
            "status": {
                "confirmed": true,
                "block_height": 625673,
                "block_hash": "0000000000000000000310649c075b9e2fed9b10df2b9f0831efc4291abcb7fb",
                "block_time": 1586732907
            },
            "value": 546
        },

    ]
}

И я использую следующий класс dart для декодирования этого JSON в Объект, с которым я могу взаимодействовать:

class UtxoData {
  final dynamic totalUserCurrency;
  final int satoshiBalance;
  final dynamic bitcoinBalance;
  List<UtxoObject> unspentOutputArray;

  UtxoData({this.totalUserCurrency, this.satoshiBalance, this.bitcoinBalance, this.unspentOutputArray});

  factory UtxoData.fromJson(Map<String, dynamic> json) {
    var outputList = json['outputArray'] as List;
    List<UtxoObject> utxoList = outputList.map((output) => UtxoObject.fromJson(output)).toList(); 

    return UtxoData(
      totalUserCurrency: json['total_user_currency'],
      satoshiBalance: json['total_sats'],
      bitcoinBalance: json['total_btc'],
      unspentOutputArray: utxoList
    );
  }
}

class UtxoObject {
  final String txid;
  final int vout;
  final Status status;
  final int value;

  UtxoObject({this.txid, this.vout, this.status, this.value});

  factory UtxoObject.fromJson(Map<String, dynamic> json) {
    return UtxoObject(
      txid: json['txid'],
      vout: json['vout'],
      status: Status.fromJson(json['status']),
      value: json['value']
    );
  }
}

class Status {
  final bool confirmed;
  final String blockHash;
  final int blockHeight;
  final int blockTime;

  Status({this.confirmed, this.blockHash, this.blockHeight, this.blockTime});

  factory Status.fromJson(Map<String, dynamic> json) {
    return Status(
      confirmed: json['confirmed'],
      blockHash: json['block_hash'],
      blockHeight: json['block_height'],
      blockTime: json['block_time']
    );
  }

}

Вот функция, которая фактически вызывает API в коде:

Future<UtxoData> fetchUtxoData() async {
    final requestBody = {
      "currency": "USD",
      "receivingAddresses": ["bc1q5jf6r77vhdd4t54xmzgls823g80pz9d9k73d2r"],
      "internalAndChangeAddressArray": ["bc1q5jf6r77vhdd4t54xmzgls823g80pz9d9k73d2r"]
    };

    final response = await http.post('https://thisisanexmapleapiurl.com', body: jsonEncode(requestBody), headers: {'Content-Type': 'application/json'} );

    if (response.statusCode == 200 || response.statusCode == 201) {
      notifyListeners();
      print(response.body);
      return UtxoData.fromJson(json.decode(response.body));
    } else {
      throw Exception('Something happened: ' + response.statusCode.toString() + response.body );
    }
  }

Однако, когда я запускаю функцию, я получаю следующая ошибка в моем редакторе:

Exception has occurred.
_TypeError (type 'int' is not a subtype of type 'double')

Я получаю его в операторе возврата UtxoData внутри метода фабрики для класса UtxoData, как показано ниже:

return UtxoData(
      totalUserCurrency: json['total_user_currency'],
      satoshiBalance: json['total_sats'],                    <<<<============= The exception pops up right there for some reason
      bitcoinBalance: json['total_btc'],
      unspentOutputArray: utxoList
    );

Это странно, потому что я знать, что API возвращает int там. totalUserCurrency и bitcoinBalance должны быть динамическими c, потому что они могут быть либо 0 (целое число), либо произвольным числом, например 12942.3232 (двойное).

Почему я получаю эту ошибку и как я могу ее исправить? Высоко ценится

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Если вы анализируете данные и не уверены, будет ли это Int или double, существует несколько решений.

Если вам нужно Int, используйте parsedData.truncate(), это работает как для Int, так и double, и он преобразуется в Int, отбрасывая десятичные дроби. Точно так же вы можете также использовать cail() или floor(), если хотите, чтобы десятичные дроби имели некоторый эффект в результате.

Итак, в вашем случае вам нужно будет сделать только так:

satoshiBalance: json['total_sats'].truncate(),

Надеюсь, это поможет!

1 голос
/ 24 апреля 2020

У меня была похожая проблема, когда сумма, которую я получал от API, варьировалась от 0 до нескольких тысяч, включая десятичные дроби. Я попробовал следующее:

this.balanceAmount = double.parse(json['total_balance']??'0.0'.toString());

Это не сработало с моим набором данных. Итак, я расширил его до следующего, который работал во всех случаях для моего набора данных. Вам может потребоваться небольшое улучшение (я).

double parseAmount(dynamic dAmount){

    double returnAmount = 0.00;
    String strAmount;

    try {

      if (dAmount == null || dAmount == 0) return 0.0;

      strAmount = dAmount.toString();

      if (strAmount.contains('.')) {
        returnAmount = double.parse(strAmount);
      }  // Didn't need else since the input was either 0, an integer or a double
    } catch (e) {
      return 0.000;
    }

    return returnAmount;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...