Как конвертировать Будущее Флаттера <dynamic>в Будущее ? - PullRequest
0 голосов
/ 29 января 2020

В прошлом я использовал http-клиент, который возвращает Future<Response>. Я заметил, что я могу вернуть другой тип внутри метода .then(), и результат конечного типа изменится в соответствии с типом того, что я возвратил в then.

Но когда я перехожу на использование пакета, который возвращает Future<dynamic>, возвращение другого типа внутри .then() больше не меняет тип конечного результата. Это продолжает приводить к Future<dynamic>. Но я могу заверить, что тип Dynami c является типом Response. Вот что я попробовал:

1-й:

Future<Response> get(String url) =>
    fetcher.get(url).then((response) => response as Response); // error: Unhandled Exception: type 'Future<dynamic>' is not a subtype of type 'Future<Response>'

2-й:

Future<Response> get(String url) =>
    fetcher.get(url) as Future<Response>; // error: Unhandled Exception: type 'Future<dynamic>' is not a subtype of type 'Future<Response>'

3-й:

Future<Response> get(String url) =>
    fetcher.get(url).then((response) { 
        final result = response as Response;
        return result;
    }); // error: Unhandled Exception: type 'Future<dynamic>' is not a subtype of type 'Future<Response>'

В прошлом:

Future<List<Model>> get(String url) =>
    client.get(url).then((response) => Model.fromJson(response.body)); // working.

Пакет, который я использовал для этого: https://pub.dev/packages/twitter_api# -example-tab-

РЕДАКТИРОВАТЬ: уточнить о сборщике:

import 'package:twitter_api/twitter_api.dart';
import "package:http/http.dart";


twitterApi fetcher = twitterApi(
    consumerKey: consumerApiKey,
    consumerSecret: consumerApiSecretKey,
    token: locker.session?.token,
    tokenSecret: locker.session?.secret
);

Future<Response> get(String path) {
    final split = url.split("?");
    final onlyPath = split[0];
    final onlyParam = split.length > 1 ? split[1] : "";
    final options = Map.fromIterable(onlyParam.split("&").where((it) => it.contains("=")), key: (e) => e.split("=")[0] as String, value: (e) => e.split("=")[1] as String);
    return fetcher.getTwitterRequest("GET", onlyPath.replaceFirst("/", "", options: options).then((response) {
        debugPrint ("GET ${response.request.url} Response: ${response.body}");
        return response as Response;
    }); 
}

Вывод:

[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: type 'Future<dynamic>' is not a subtype of type 'Future<Response>'
#0      TwitterApiProvider.fetchUser (package:feazy/src/resources/twitter_api_provider.dart:11:70)
#1      Repository.fetchUser (package:feazy/src/resources/repository.dart:19:27)
#2      _HomeState.twitterLogin (package:feazy/src/ui/home.dart:50:21)
...
GET https://api.twitter.com/1.1/users/show.json?screen_name=somescreenname Response: {"id":<int>,"id_str":<string>,"name":"Some name","screen_name":"somescreenname",...

РЕДАКТИРОВАНИЕ 2: при дальнейшей проверке я замечаю, что в IDE среда IDE сообщает мне, что тип возвращаемого значения fetcher.getTwitterRequest() не Future<dynamic>, а dynamic , Поэтому я изменяю свой код следующим образом, но он все равно не будет работать.

Future<Response> get (String path) {
    ...
    final future = authClient.getTwitterRequest(...).then((response) {
        debugPrint ("POST ${response.request.url} Response: ${response.body}");
        return response as Response;
    });
    final futureResponse = future as Future<Response>;
    return futureResponse;
}

В этом случае ошибка на final futureResponse = future as Future<Response>;, говоря то же самое: Unhandled Exception: type 'Future<dynamic>' is not a subtype of type 'Future<Response>' in type cast.

1 Ответ

0 голосов
/ 29 января 2020

ИМХО, все ваши примеры в порядке, но ошибка на самом деле говорит нам, что вы пытались привести Future<Response> в Future<dynamic>

ОБНОВЛЕНИЕ

Вы можете использовать async await, что-то вроде этого:

Future<Response> get(String path) async {
    final split = url.split("?");
    final onlyPath = split[0];
    final onlyParam = split.length > 1 ? split[1] : "";
    final options = Map.fromIterable(onlyParam.split("&").where((it) => it.contains("=")), key: (e) => e.split("=")[0] as String, value: (e) => e.split("=")[1] as String);
    final response = await fetcher.getTwitterRequest("GET", onlyPath.replaceFirst("/", "", options: options); 
    return response as Response;
}
...