chopper icon indicating copy to clipboard operation
chopper copied to clipboard

Will support Rxdart?

Open KingWu opened this issue 5 years ago • 9 comments

I am Android developer. It is glad to see this project. Will it support Rx pattern? Also, capture common errors like network unavailable, status code not 200 and throw exception.

If supported Rx pattern, assume to like it || V

import "dart:async";
import 'package:chopper/chopper.dart';

part "my_service.chopper.dart";

@ChopperApi(baseUrl: "/resources")
abstract class MyService extends ChopperService {
  static MyService create([ChopperClient client]) => _$MyService(client);

  @Get(url: "{id}")
  Observable<Response> getResource(@Path() String id);

  @Get(headers: const {"foo": "bar"})
  Observable<Response<Map>> getMapResource(@Query() String id);

  @Post(url: 'multi')
  @multipart
  Observable<Response> postResources(
    @Part('1') Map a,
    @Part('2') Map b,
    @Part('3') String c,
  );

  @Post(url: 'file')
  @multipart
  Observable<Response> postFile(
    @FileField('file') List<int> bytes,
  );
}

KingWu avatar Jun 17 '19 06:06 KingWu

In RxDart, a Future<T> can be treated as a Single<T> so this more or less already supports RxDart. It makes more sense to model API calls as Single<T> anyways, since there's going to be one response per request.

paulblakely avatar Jun 20 '19 18:06 paulblakely

From what I remember with Rx Pattern and retrofit, the request is not trigger until you start listening the Observable, which is not really common in Dart and I personally don't see the advantage of it (maybe I am wrong)

But if you just want to use Observable methods you can use Observable.fromFuture

final stream = Observable.fromFuture(service.getResource('id'))

lejard-h avatar Jul 01 '19 20:07 lejard-h

the request is not trigger until you start listening the Observable, which is not really common in Dart

As far as I know, this is how Futures behave as well. No work is done with a Future until you await or .then it.

paulblakely avatar Jul 01 '19 20:07 paulblakely

the request is not trigger until you start listening the Observable, which is not really common in Dart

As far as I know, this is how Futures behave as well. No work is done with a Future until you await or .then it.

not sure about this.

main() async {
  test();
  await Future.delayed(Duration(seconds: 5));
  print('world ${new DateTime.now()}');
}

Future test() async {
  print('hello ${new DateTime.now()}');
}

test function is executed even if not await of then

lejard-h avatar Jul 29 '19 19:07 lejard-h

Another point where adding native rxdart support would be great is the need to map response everytime to a specific body:

Observable<List<Plant>> fetch() => Observable.fromFuture(
        api.getPlants(),
      ).map((result) => result.body);

It's a little annoying :P

wrozwad avatar Aug 22 '19 15:08 wrozwad

And because it's better to throw any Exception using reactive streams I add:

  • custom errorConverter: HttpExceptionErrorConverter()
class HttpExceptionErrorConverter extends ErrorConverter {
  @override
  Response convertError<ErrorType, T>(Response response) {
    final base = response.base;
    final message = "${base.statusCode} ${response.body}";
    return response.replace<dynamic>(
      bodyError: HttpException(message, uri: base.request.url),
    );
  }
}
  • and custom interceptors: <dynamic>[ThrowExceptionInterceptor()]
class ThrowExceptionInterceptor implements ResponseInterceptor {
  @override
  Response onResponse(Response response) =>
      response.error is Exception || response.error is Error
          ? throw response.error
          : response;
}

wrozwad avatar Aug 22 '19 16:08 wrozwad

this is calladapter in retrofit. I really hope this can be support.

akdeveloper-android avatar Sep 02 '19 02:09 akdeveloper-android

We should definitely do this.

However, right now I'm working on the docs so Chopper can be as user-friendly and documented as possible. There are some roadblocks related to library maintenance along the way which should be cleared (like nullability support), but support for Rx types should be discussed and implemented in the near future. No promises though, maybe this year. 😅

stewemetal avatar Jan 15 '21 22:01 stewemetal

But we have a support, as I see. :) This is a little addition, to use the map call. Or to use Singles. :)

JEuler avatar Jan 16 '21 20:01 JEuler