How do I inherit from an Observable<T>? - rx-java2

I want to build an event broker class that inherits from Observable<EventArgs>. In the .NET implementation of Rx, you can simply implement IObservable<EventArgs>; furthermore, in .NET the publish() method just takes the argument that you want the subscribers to receive.
Can someone explain how this is done in Java? All I want is a class who inherently behaves as Observable<Foo>.

In most cases, there is no necessity to implement your own Observable inheritor. There is a bunch of fabrics methods to create Observable and handle it's behavior. For example:
Observable.create(new ObservableOnSubscribe<String>() {
#Override public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("New event");
emitter.onError(new Error());
emitter.onComplete();
}
});
But, if you really need to create exactly an inheritor it is not difficult either.
class MarkedObservable extends Observable<String> {
#Override protected void subscribeActual(Observer<? super String> observer) {
observer.onNext("Message");
observer.onError(new Error());
observer.onComplete();
}
}

Related

Flutter, Dart. Create anonymous class

Maybe it's really dumb question. But I cannot believe there is no resources, where it's described. Even from the official documentation. What I'm trying to do, it's create Anonymous class for the next function.
How to create Anonymous class in Dart with custom function something like next in Kotlin?
Handler(Looper.getMainLooper()).post(Runnable() {
#override
open fun run() {
//...
}
private fun local() {
//....
}
})
Dart does not support creating an anonymous class.
What you're trying to do is not possible.
On the other hand, you can create anonymous functions. So you could use that to mimic an anonymous class.
The idea is to add a constructor of your abstract class, that defer its implementation to callbacks.
abstract class Event {
void run();
}
class _AnonymousEvent implements Event {
_AnonymousEvent({void run()}): _run = run;
final void Function() _run;
#override
void run() => _run();
}
Event createAnonymousEvent() {
return _AnonymousEvent(
run: () => print('run'),
);
}
It's not strictly the same as an anonymous class and is closer to the decorator pattern. But it should cover most use-cases.
This is an alternative way, but not fully equivalent:
Problem, e.g.:
I would like to implement OnChildClickListener inline in my code without class. For this method:
void setOnChildClickListener(OnChildClickListener listener) {
...
}
Instead of this:
abstract class OnChildClickListener {
bool onChildClick(int groupPosition, int childPosition);
}
use this:
typedef OnChildClickListener = Function(int groupPosition, int childPosition);
And in code you can implement it in this way:
listView.setOnChildClickListener((int groupPosition, int childPosition) {
// your code here
});
In other words do not use abstract class, but use typedef.

RxAndroid: How to add additional methods in Observer and Observable

Observer has onNext(), OnError() and onComplete().
Is there a way to add an additional method?
There is a possibility that the object received via the stream is of two types instead of the same type. And both possibilities are a success scenario. They are just handled differently by the observer.
Now, with callbacks, one would add a new method to handle this.
But not sure how this would be done with Rx.
Or is there another way of handling this without having to add a new method?
Thanks
I think the best way to achieve this is by using a common super class which can hold both objects.
In Kotlin you can do this with sealed class in Java do it with a simple POJO. One downside is that you have to use instanceOf and casting to use the actual type.
public class Result<T> {
public T result;
public Result(T result) {
this.result = result;
}
}
public class Result1 extends Result<Object1> {
public Result1(Object1 result) {
super(result);
}
}
public class Result2 extends Result<Object2> {
public Result2(Object2 result) {
super(result);
}
}
Your Observable can emit Result objects, and you can cast to either result based on what you got on the onNext method.

Creating Custom Operators in RxJava2?

I'm having trouble finding an example of how to make a custom operator with RxJava 2. I've considered a few approaches:
Using Observable.create, and then flatMaping on it from the source observable. I can get this working, but it doesn't quite feel right. I end up creating a static function which I provide the source Observable, and then flatMap on the source. In the OnSubscribe, I then instantiate an object that I pass the emitter to, which handles and manages the Observable / Emitter (as it's not trivial, and I want everything as encapsulated as possible).
Creating an ObservableOperator and providing it to Observable.lift. I can't find any examples of this for RxJava 2. I had to debug into my own example to make sure my understanding of upstream and downstream were correct. Because I can't find any examples or documentation on this for RxJava 2 I'm a little worried I might accidentally do something I'm not supposed to.
Create my own Observable type. This seems to be how the underlying operators work, many of which extend AbstractObservableWithUpstream. There is a lot going on here though, and it seems easy to miss something or do something I shouldn't. I'm not sure if I'm supposed to take an approach like this or not. I stepped myself through the mental process, and it seems like it can get hairy pretty quickly.
I'm going to proceed forward with option #2, but thought it worthwhile to ask what the supported method for doing this was in RxJava2 and also find out if there was any documentation or examples for this.
Writing operators is not recommended for beginners and many desired flow patterns can be achieved via existing operators.
Have you looked at RxJava's wiki about writing operators for 2.x? I suggest reading it from top to bottom.
using create() is possible but most people use it to emit the elements of a List with a for-each loop, not recognizing that Flowable.fromIterable does that.
We kept this extension point although RxJava 2 operators don't use lift() themselves. If you want to avoid some boilerplate with option 3. then you may try this route.
This is how RxJava 2 operators are implemented. AbstractObservableWithUpstream is a small convenience and not necessary for external implementors.
This may help you. I implement operator RxJava2 to handle APiError. I used lift operator.
See the example.
public final class ApiClient implements ApiClientInterface {
...
#NonNull
#Override
public Observable<ActivateResponse> activate(String email, EmailData emailLinkData) {
return myApiService.activate(email, emailData)
.lift(getApiErrorTransformer())
.subscribeOn(Schedulers.io());
}
private <T>ApiErrorOperator<T> getApiErrorTransformer() {
return new ApiErrorOperator<>(gson, networkService);
}
}
And then you can find custom operator
public final class ApiErrorOperator<T> implements ObservableOperator<T, T> {
private static final String TAG = "ApiErrorOperator";
private final Gson gson;
private final NetworkService networkService;
public ApiErrorOperator(#NonNull Gson gson, #NonNull NetworkService networkService) {
this.gson = gson;
this.networkService = networkService;
}
#Override
public Observer<? super T> apply(Observer<? super T> observer) throws Exception {
return new Observer<T>() {
#Override
public void onSubscribe(Disposable d) {
observer.onSubscribe(d);
}
#Override
public void onNext(T value) {
observer.onNext(value);
}
#Override
public void onError(Throwable e) {
Log.e(TAG, "onError", e);
if (e instanceof HttpException) {
try {
HttpException error = (HttpException) e;
Response response = error.response();
String errorBody = response.errorBody().string();
ErrorResponse errorResponse = gson.fromJson(errorBody.trim(), ErrorResponse.class);
ApiException exception = new ApiException(errorResponse, response);
observer.onError(exception);
} catch (IOException exception) {
observer.onError(exception);
}
} else if (!networkService.isNetworkAvailable()) {
observer.onError(new NetworkException(ErrorResponse.builder()
.setErrorCode("")
.setDescription("No Network Connection Error")
.build()));
} else {
observer.onError(e);
}
}
#Override
public void onComplete() {
observer.onComplete();
}
};
}
}

GWT - run command exactly once per event loop

I'm writing some wrapper classes around zurb foundation.
Foundation widgets need an init() function to be called after the elements have been added to the DOM.
I can accomplish this easily enough with this method:
public static void initWidgets() {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
#Override
public void execute() {
foundationInit();
}
});
}
...where foundationInit() is a JSNI call to the foundation init() function. I then add a call to initWidgets() in the constructor of any foundation element. So far so good.
However, if multiple foundation widgets are added to the DOM during a particular event loop, then the init() method will be called multiple times. Foundation doesn't actually care about this, but it would be nice to find a way around this.
Is there any scheduler functionality / pattern that'd allow me to schedule a particular command to run only once, no matter how many times the schedule method is called with that command?
Something like: scheduleDeferredIfNotAlreadyScheduled(Command c)
I don't know how to get a handle on the event loop, so I don't know how to reset a flag that'd tell me whether or not to add the command or not.
I don't know any Scheduller command to do that, but it could be done with a static boolean variable, e.g.:
private static boolean initialized;
public static void initWidgets() {
initialized = false;
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
#Override
public void execute() {
if (!initialized) {
initialized = true;
foundationInit();
}
}
});
}
In such case I usually use Guava's Supplier.double checked locking is really safe.
public static Supplier<Boolean> supplier=Suppliers.memoize(new Supplier<Boolean>() {
#Override
public Boolean get() {
foundationInit();
return true;
}
});
public static void initWidgets() {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
#Override
public void execute() {
boolean initialized=supplier.get();
}
});
}

RxJava (or Rx.NET) equivalent of ReactiveCocoa's RACObserve

Given an arbitrary field on a Java object, I want to create an Observable that will watch that field and push a new result to an Observer every time the value of the field changes. ReactiveCocoa has a macro called RACObserve, which appears to do exactly this.
I want to know how to implement similar functionality using RxJava.
For example, say I had the following simple class:
public class Foo {
enum State {
Idle,
Ready,
Error
}
private State currentState = State.Idle;
//methods that can change currentState
}
I want to create an Observable<State> that will push the new state to an Observer every time something changes the value of currentState.
In ReactiveCocoa, it looks like I would write something sort of like the following (please excuse my pseudo Objective-C):
[RACObserve(self, currentState) subscribeNext:^(NSString *newState) {
NSLog(#"%#", newState);
}];
How would I achieve similar functionality in RxJava? I'm thinking that I may need to wrap all changes to currentState in a setter, but it's not clear to me where I should then call Observable.create and how to feed the changes of currentState to an Observer.
ReactiveCocoa is actually more similar to ReactiveUI (http://www.reactiveui.net) than just plain Rx. And in ReactiveUI, you can use this.WhenAnyValue(x => x.PropName) to do exactly what you want.
I stumbled across this same problem recently, I ended up using PropertyChangeListener, which will emit an object when a property is changed, see the following:
Update Listener:
public class GameUpdateListener {
public static Observable<Object> changed(Game game) {
final BehaviorSubject<Object> subject = BehaviorSubject.create((Object)game);
game.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
subject.onNext( (Object)propertyChangeEvent.getNewValue());
}
});
return subject;
}
}
Some custom object:
public class Game {
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
...
public setSomeField(String field){
this.field = field;
pcs.firePropertyChange("field", this.field, field);
}
public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
pcs.addPropertyChangeListener(propertyChangeListener);
}
...
}
Observe:
Game game = new Game();
GameUpdateListener listener = new GameUpdateListener();
final Observable<Object> gameObserver = listener.changed(game);
gameObserver.subscribe(new Action1<Object>() {
#Override
public void call(Object o) {
Log.e(TAG, "Object Changed");
}
});
game.setSomeField("New value");
This will work fine as long as you don't need to instantiate your object again. Perhaps a solution to this is to create a local setter method and emit a change there.
Since your question title contains "or Rx.NET", here is my suggestion (I dunno bout RxJava, you may find something similar).
You probably will have to leverage some sort of mechanism in the setter. The standard way in .NET is by using the INotifyPropertyChanged interface.
Then by firing the events, you can create an IObservable<T> from this stream by using
Observable.FromEvent<TEvent, TArgs>()
You can find a really good example of what you want to do (.NET) here.
(credits to Rob Foncesa-Ensor)
I think what you are after is a Subject<T>. It implements IObserver<T>, so you can call OnNext(T) to fire a new value, as well as IObservable<T>, which you can expose it as publicly so it can be subscribed to.
If you need it to fire the latest value to new subscribers, you can use a ReplaySubject<T> with a buffer size of 1.
Here's a basic implementation:
public class SomeService
{
private Subject<int> values = new Subject<int>();
public IObservable<T> Values
{
get
{
// AsObservable prevents it from being cast back to Subject
return values.AsObservable();
}
}
// Private; called by some internal mechanism
private void SetValue(int newValue)
{
newValue.OnNext(newValue);
}
}