These are chat archives for ReactiveX/RxJava

Sep 2018
Ignacio Baca Moreno-Torres
Sep 21 2018 12:29
@incube8r this is how I would do it
// create the `input` outside Single.create! add it to the view, not in the observable
HTMLInputElement input = Elements.input("file").get();
// now just listen to changes using RxGWT
Observable<InputEvent> inputChange$ = RxElemento.fromEvent(input, EventType.change);
// map to file, this is just an example, use whatever code you have in `getFile`
Observable<File> fileSelected$ = inputChange$.map(ev -> ev.dataTransfer.files.item(0));
// move this as a method, maybe I'll add this to RxGWT
Function<File, Single<String>> fileAsDataUrl = file -> Single.create(em -> {
    FileReader reader = new FileReader();
    reader.onload = ev -> { em.onSuccess(reader.result.asString()); return null; };
    reader.onerror = ev -> em.tryOnError(new RuntimeException(/*TODO*/));
// combine the file with the fileAsDataUrl, or use switchMap to cancel previous
Observable<String> dataUrlSelected$ = fileSelected$.flatMapSingle(fileAsDataUrl);
// again, flatMap the entity, I think returning a "success" boolean is bad idea, use
// exception to indicate exceptional cases, I'll map it so I can return the entity
Observable<Entity> selectedEntity$ = dataUrlSelected$.flatMapSingle(url -> {
    Entity entity = new Entity(entityType).entityId(entityId);
    return entity.blobProperty(blobName, url).map(n -> {
        if (n) return entity; else throw new Exception(/*TODO*/);
    } );
// so at that point, when you subscribe you will listen to the ready entity instances
selectedEntity$.subscribe((Entity entity) -> console.log(entity));
Ignacio Baca Moreno-Torres
Sep 21 2018 18:26
@incube8r so the important conclusion is this 2 points! apply in order, bc the scond condition should be applied after the first point has been resolved
  1. always use rx types, if you add a callback, promise, completablefuture or any alternative async structure, wrap it with a rx type, rx compose only with other rx types, and you use rx bc it can be composed (I like to think that rxjava is like a callback unifier), this will assert that rxjava chain errors and cancelation correctly too, wich is the the mayor difference with raw callback and other alternatives
  2. never subscribe into a subscription, always compose the rx types, there are really a lot of operator, but atleast use on of flatMap, concatMap or switchMap. this is critical to allow rx to chain errors and cancelation correctly, if you subscribe into a subscription, then you are just callback-programming, and IMO if you mix rx and callback-programing is going to be an absolute hell, with just the disvantages of both sides
Ignacio Baca Moreno-Torres
Sep 21 2018 18:34
I’m not 100% sure, but we almost never need to debug the rx stack, and we have really few unexpected situation with rx, and I think this is bc we ALWAYS follow this 2 simple rules! this makes composition perfect (subscribe, next, complete, error and cancel signaling chained corretly in any situation) so the code much more predictable too; hehe not sure, but I’m starting to think that most of the people that complaing about rx problems and rx debugging, do not follow this rule, this breaks the chain and requires you to debug the code to find where the [error or cancelation] has gone
David Karnok
Sep 21 2018 19:17
My experience is that pretty often, the code is full of very similar looking flows and the stacktrace listing the involved operators is not enough to locate the problematic flow. This is also apparent when map fails due to null returns and the stacktrace points to the RxJava operator, not the lambda of the developer that returned the null to the operator.
Ignacio Baca Moreno-Torres
Sep 21 2018 19:50
yep, this is true, but the solution is reasonable easely… use the “jump to type source” debug action
Dan O'Reilly
Sep 21 2018 21:27
that doesn't help you when all you have is a stack trace in a log file :)
Ignacio Baca Moreno-Torres
Sep 21 2018 21:28
yep, true hehe I was thinking of that, it must be a reproducible error
we use stop on exception alot :wink:
but, all errors must be reproducible, if not, why you even care to fix it :stuck_out_tongue_winking_eye: