Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Pulkit Kumar
    @pulkitkumar
    @neee serviceReturnObservable2.getSomeData(r.getValue()) should emit an object which has everything you need to chain it further. Since it is already accepting value emitted by ServiceReturnObservable1, you should be able to add those values to the object emitted by ServiceReturnObservable2 .
    Dan O'Reilly
    @dano
    @neee i usually .map to a tuple type inside of the first flatMap call, or nest the second flatMap call inside the first
    i have a bunch of helpers for automatically "chaining" the second emitted value into a tuple with the previous emitted value, and then unpacking the tuple in the next call
    So you'd end up with
    ServiceReturnObservable1.getData()
        .flatMap(chainObs(r -> serviceReturnObservable2.getSomeData(r.getValue())))
        .flatMap(unpack((r1, r2) -> ...))
    Ignacio Baca Moreno-Torres
    @ibaca
    you know this sorcery works since java8 and can be saved in var since java10 :scream:
    Observable.just(1,2,3,4)
            .flatMap(n -> Observable.just("a","b","c")
                    .map(s -> new Object() { Integer num = n; String str = s; }))
            .subscribe(obj -> System.out.println(obj.num + ":" + obj.str));
    Ricky Limka
    @rcklmk_twitter

    Hey everyone, today I encountered a strange behavior with Observable.create:

    ...
    private ObservableEmitter<Action> extEmitter;
    
        public Test() {
            Observable<Action> actions = Observable.create(emitter -> {
                extEmitter = emitter;
    
                emitter.onNext(Action.TEST);
                emitter.onNext(Action.REVERT);
                emitter.onNext(Action.TEST);
                emitter.onNext(Action.REVERT);
            });
    
    
            Observable<Action> reverts = actions.filter(Action.REVERT::equals);
            Observable<Action> tests = actions.filter(Action.TEST::equals);
    
            Observable.merge(tests, reverts).subscribe(System.out::println);
    
            extEmitter.onNext(Action.TEST);
            extEmitter.onNext(Action.REVERT);
            extEmitter.onNext(Action.TEST);
            extEmitter.onNext(Action.REVERT);
        }
    ...

    Does anyone know why using extEmitter (emitter outside of lambda) emits different results than emitter inside lambda?

    ↑ what is the common practice for exporting emitter outside for pushing custom values from other java classes?
    Ricky Limka
    @rcklmk_twitter
    I should have used Rx.Subject instead?
    Incubator
    @incube8r
    Hello
    Aadi Deshpande
    @cilquirm
    Hi, i'm having trouble mapping a flowable. I am getting an error that I kinda sorta understand but I can't understand why I 'm getting it:
    [Java] The parameterized method <Tuple2<Entity,SourceEntry>>map(Function<? super Entity,? extends Tuple2<Entity,SourceEntry>>) of type Flowable<Entity> is not applicable for the arguments (Function<Entity,Tuple2<Entity,SourceEntry>>)
    Incubator
    @incube8r

    Hello, in this code (below), is it possible get the FileObject (also), I mean to subscribe to get it?)

    public Single<Boolean> uploadFile(String entityType, String entityId, String blobName){
        return Single.create(e -> {
            uploadElement = DOM.createElement("input");
            uploadElement.setAttribute("type", "file");
            uploadElement.setAttribute("accept", "*/*");;
            Event.sinkEvents(uploadElement, Event.ONCHANGE);
            Event.setEventListener(uploadElement, event -> {
                final FileObject fileObject = (FileObject) getFile(event);
                readAsDataURL((FileObject) fileObject, new FileReaderCallback() {
                    @Override
                    public void onLoad(String data) {
                            Entity entity = new Entity(entityType);
                            entity.setEntityId(entityId);
                            entity.setBlobProperty(blobName, data).subscribe(isSuccess -> {
                                e.onSuccess(isSuccess);
                            }, error -> {
                                e.onError(error);
                            });
                    }
                });
            });
            click();
        });
    }

    Or I have to change the Single<Boolean> to something else that will be able to get the FileObject and pass it one.onSuccess?

    Ignacio Baca Moreno-Torres
    @ibaca
    Something eles? Hehe just use Single<FileObject>
    Incubator
    @incube8r
    I also need to get the boolean status
    so I have to create a POJO to have both Boolean and FileObject at the same time?
    Ignacio Baca Moreno-Torres
    @ibaca
    Boolean status? It is always true, this is not a status
    Incubator
    @incube8r
    the method entity.setBlobProperty emits isSuccess which is the status either true or false
    Ignacio Baca Moreno-Torres
    @ibaca
    You are also adding a listener and never removing it, use the rxgwt utilities for observing event which handle that correctly
    Oh I see, and this is an Observable? Remember, never ever subscribe inside another subscription, use flap Map instead
    RxJava is like callback on steroids, so whenever you see a callback you can trivially wrap it as a RxJava type, readasdataurl has a callback, so wrap it as a rxtype and flatMap too (when I say flatMap, you can use the one you need, flatMap, concatMap, switchMap...)
    Incubator
    @incube8r
    problem here is that Event.setEventListener blocking that chain
    I mean I can't do return Observable... inside that anonymous class
    I could flatMap outside but the typed return would change
    Ignacio Baca Moreno-Torres
    @ibaca
    use RxGWT, then flapMap the event with the ReadAsDatUrl Observable wrapper
    Incubator
    @incube8r
    can you show me how to do this the right way using the RxGWT utilities?
    Ignacio Baca Moreno-Torres
    @ibaca
    :grimacing: sorry I'm out, but yep I'll help you tomorrow :wink:
    Ignacio Baca Moreno-Torres
    @ibaca
    @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*/));
        reader.readAsDataURL(file);
        em.setCancellable(reader::abort);
    });
    // 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
    @ibaca
    @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
    @ibaca
    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
    @akarnokd
    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
    @ibaca
    yep, this is true, but the solution is reasonable easely… use the “jump to type source” debug action
    image.png
    Dan O'Reilly
    @dano
    that doesn't help you when all you have is a stack trace in a log file :)
    Ignacio Baca Moreno-Torres
    @ibaca
    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:
    Incubator
    @incube8r
    @ibaca thanks for the help
    k.watanabe
    @hackugyo
    Hi all
    How do you handle warnings of return values of subscirbe() with trello/RxLifecycle? subscirbe() has @CheckReturnValue annotation. Although I handle Disposable by compose(bindToLifecycle()) I must care about return values or suppress each warnings. How can I avoid this?
    Should I use uber/AutoDispose instead of RxLifecycle?
    Ignacio Baca Moreno-Torres
    @ibaca
    I don't use android, but in gwt I use this and I pass the whole Observable instead of subscribing it https://github.com/intendia-oss/rxgwt/blob/2.x/core/src/main/java/com/intendia/rxgwt2/user/RxWidget.java
    This also has the advantage of been able to decide whet it gets subscribes and to reconnect if something goes wrong
    This idea can be trivially applied over RxLifecycle, so the warning will disappear (and other advantages which are even more important), but note that if you do this, then you really should only add binding in your activity constructor to avoid to add duplicate bindings
    k.watanabe
    @hackugyo
    Thanks I will try! @ibaca
    Essentially, what suppress warnings in your suggestion is adding the disposable to class-scope (or, activity-scope) disposable list, I think. RxLifecylce will manage disposables, so perhaps what I need is just a trivial extension methods:
        @SuppressWarnings("CheckReturnValue")
        fun <T> Maybe<T>.subscribeSilently(onSuccess: (T) -> Unit): Disposable? {
            return subscribe(onSuccess)
        }
    Ignacio Baca Moreno-Torres
    @ibaca
    @hackugyo In our case, we add the Observable itself to de lifecycle manager, and it is the manager the responsible of subscribing it when the phase start, and unsubscribe it on finish, so for example if you add an observable to the method onResume(observable) (added one time, recommended to do it in the activty constructor), it will subscribe it in onResume phase, and unsbuscribe it on onPause, this will allow to add some retry to the observable and to caught and handle errors a bit more specific than with the global handler. But yep, to just avoid the warning your solution is easier :+1:
    Luca Looz
    @llooz
    what is the difference between .to and .compose?
    Dayan Ruben Gonzalez
    @dayanruben
    Xcg,
    i
    Vc. BB. BVB BV gy vc gosta m
    Obrigado jmm
    Não. obrigado ZX, não sei como. ,
    Ii,t
    Não