Observable - don't return results until successful completion - system.reactive

I have an IObservable<T> that comes from parsing a CSV, spitting out a parsed result for each row.
There's an issue right now with corruption in the source data that I cannot detect until I've already reached the end of the file: with the current Reactive setup, that means I've already emitted bad results.
Until the source data issue is resolved, is there a way I can "buffer" (hold back) an entire IObservable result stream such that no results are emitted until it has completed successfully? No method signatures should change (the source should still return IObservable<T>).

It's easy, just do this:
var query = source.ToArray();
IDisposable subscription =
source.Subscribe(allRows =>
{
/* do something with `allRows` */
});
The .ToArray() operator turns an IObservable<T> that returns zero or more values into an IObservable<T[]> that returns one array of T that contains zero or more elements.
You must make sure that your source observable ends with an OnCompleted for the array to be produced.
You can also use .ToList() which returns an IList<T> rather than an T[].
If you want to return a IObservable<T> rather than a IObservable<T[]> simply put a .SelectMany(t => t) after the .ToArray(). Keep in mind that this means that all the values will come at once as soon as the source observable completes.

I'm sure there's a nicer way, but this should work:
// csvObservable is your existing observable
var waitTillEndObservable = csvObservable.ToList().Wait().ToObservable();
This converts to a list, waits until it's done, and then converts back to an observable so that it can be used interchangeably with your existing csvObservable.

Related

want to make a method that toggle my transaction with expense to income and vice versa in flutter

I have created a method to toggle transaction type, like converting expense to income and income to expense...
and I created following method
void swapTransaction(TransactionModel transaction)
{
transaction.isExpense=!transaction.isExpense;
update();
}
it worked fine but than I was forced to apply following method,
void swapTransaction(TransactionModel transaction)
{
int index=_transactions.indexOf(transaction);
_transactions[index].isExpense=!_transactions[index].isExpense;
update();
}
here I want to know what is the better method to apply... is there any big difference?
I'm not sure if such questions are suitable for this site, as it can be "opinion based" but here's my take:
I think the second method is better since you are updating the actual _transactions list, but in the first example, you are just updating what's getting passed into the function - the TransactionModel, so you're not actually changing the list of _transactions.
According to me, second one is better.
In first one you are passing one copy of object to update, which is just used within that function. While in second one you are actually updating your actual list of transaction, which you used to display.

StreamBuilder triggers a method twice while the same operation as a variable triggered only once

I have a StreamBuilder that accepts a stream from my service. It looks like this:
StreamBuilder(
stream: MyService.getStream$()
builder (...)
);
Plus, I have my service with the following method:
getStream$() {
print('being printed twice');
return Observable.just('text')
.doOnData(() => print('being printed twice too'));
}
When I run the app, I get the following prints being printed twice (each).
But, when I change the following implementation as a variable, it runs just once:
Observable getStream = Observable
.just('text')
.doOnData((data) => print('being printed once');
Of course, in the example above, I would use variables, but in my original code, I'm unable to do so because I'm depended on the instance properties.
What I can do, is to declare an Observable variable and in the constructor to set it to my desired observable. Although, this solution sounds like a workaround, and I'm not sure why would the the method would be triggered twice.
Any ideas?
StreamBuilder is rebuild every time build method is invoked. It means that MyService.getStream$() is evaluated with each invocation and creates new Observable. If you assign Observable to variable it will be created once and reused between build calls.
Take a look at this question Future running twice because it's in build method, how to fix it?
it's about future but the mechanism is same.

How to pass a variable along when chaining observables?

I'm pretty new to RxJava, and whenever I have a case where I need to pass return data from one observable down the chain until a call to 'subscribe' - I have trouble understanding how to do it the 'Reactive' way without any patches...
For example:
Observable<GameObject> obs1 = func1();
Observable<GameObject> obs2 = func2();
Observable<GameObject> obs3 = func3();
Observable<GameObject> obs3 = func4();
I would like to emit obs1 and obs2, get their result, then emit obs3 then obs4 and then end the chain with subscribe while having the access to the results of obs1,obs2,obs3 and obs4.
The order of the calls is important, I need obs1 and obs2 to complete before obs3 is executed.
same goes for obs3 and obs4 - I need obs3 to complete before obs4 is executed.
How can I do that?
I know it's a pretty digested question - but this is one of the most problematic issues when a developer starts to know rxJava.
Thanks.
You can do it using Observable.zip and simple Observable.map/Observable.flatMap:
Observable.zip(obs1, obs2, (res1, res2) -> {
// do stuff with res1, res2
return obs3.flatMap(res3 -> {
// do stuff with res1, res2, res3
return obs4.flatMap(res4 -> {
// do stuff with res1, res2, res3, res4
return result;
});
});
});
This will force your scheduling requirements:
observables 1 and 2
observable 3
observable 4
Since I had the same kind of doubts in mind a while ago, the question seams to be related to how Observables really work.
Let's say you created obs1 and obs2 using something like:
Observable<GameObject> obs1 = Observable.create(...)
Observable<GameObject> obs2 = Observable.create(...)
You have 2 independent and disconnected streams. That's what you want when each of them are supposed to do something like a network request or some intensive background processing, which can take some time.
Now, let's say you want to watch for both results and emit a single value out of them when they get ready (you didn't say explicitly that, but it's gonna help you understand how it works). In this case, you can use the zipWith operator, which takes a pair of items, the first item from the first Observable and the second item from the second Observable, combine them into a single item, and emit it to the next one in the chain that may be interested on it. zipWith is called from an Observable, and expects another Observable as param to be zipped with. It also expects a custom function that knows how to zip the 2 source items and create a new one out of them.
Observable<CustomObject> obs3 = obs1.zipWith(obs2, new Func2<GameObject, GameObject, CustomObject>() {
#Override
public CustomObject call(GameObject firstItem, GameObject secondItem) {
return new CustomObject(firstItem, secondItem);
}
});
In this case, the CustomObject is just a pojo. But it could be another long running task, or whatever you need to do with the results from the first two Observable items.
If you want to wait for (or, to observe!) the results coming from obs3 you can plug another Observable at the end, which is supposed to perform another piece of processing.
Observable<FinalResult> obs4 = obs3.map(new Func1<CustomObject, FinalResult>() {
#Override
public FinalResult call(CustomObject customObject) {
return new FinalResult(customObject);
}
});
The map operator transforms (or maps) one object into another. So you could perform another piece of processing, or any data manipulation, and return a result out of it. Or your FinalResult might be a regular class, like CustomObject, just holding references to the other GameObjects.. you name it.
Depending how you created your Observables, they may not have started to emit any items yet. Until now you were just creating and plugging the data pipes. In order to trigger the first task and make items flow in the stream you need to subscribe to it.
obs4.subscribe();
Wrapping up, you don't really have one single variable passing along the whole chain. You actually create an item in the first Observable, which notifies the second one when it gets ready, and so on. Additionally, each step (observable) transforms the data somehow. So, you have a chain of transformations.
RxJava follows a functional approach, applying high order functions (map, zip, filter, reduce) to your data. It's crucial to have this clear. Also, the data is always immutable: you don't really change an Observable, or change your own objects. It creates new instances of them, and the old objects will eventually be garbage collected. So obs1.zip(...) doesn't change obs1, it creates a new Observable instance, and you can assign it to a variable.
You can also drop the variable assignments (obs1, obs2, obs3 etc) and just chain all methods together. Everything is strongly typed, so the compiler will not let you plug Observables that don't match each other (output of one should match input of the next).
I hope it gives you some thoughts!

What is this ScalaRX code doing?

So I'm pretty new to both Scala and RX. The guy who knew the most, and who actually wrote this code, just left, and I'm not sure what's going on. This construct is all over his code and I'm not really clear what its doing:
def foo(List[Long]) : Observable[Unit] =
Observable {
subscriber => {
do some stuff
subscriber.onNext()
subscriber.onCompleted()
}
I mostly get do some stuff, and the calls to subscriber. What I don't get is, where does subscriber come from? Does subscriber => { instantiate the subscriber? What does Observable { subscriber => { ... } } do/mean?
If you take a look at the Observable companion object documentation, you will see an apply method that takes a function of type (Subscriber[T]) ⇒ Unit. So, when you call Observable{withSomeLambda}, then this is the same as calling Observable.apply{withSomeLambda}
And, if you go all the way to the source code you will see that this is really returning
toScalaObservable(rx.Observable.create(f))
where f is the lambda that you passed in.
So, subscriber is just the parameter of the lambda. It is passed in by the caller of that function.
This code is creating a new Observable as described here.
Basically when a downstream component subscribes to this stream, this callback is called. In the callback we determine when we, as a data source, will call onNext(v: T) which is how we pass each element we are generating to them, and when we will call onCompleted() which is how we tell the subscriber that we are done sending data.
Once you have created an Observable you can start calling Observable operators, which will either result in another, compound Observable, or will result in a terminating condition which will end the process, and generally result in a final result for the flow (often a collection or aggregate value).
You don't use the List in your question, but normally if you wanted to make a reactive stream out of a list you would call Observable.from().
PS: I think this is RxJava code.

using Reactive Extensions to monitor IEnumerable

I'm connecting to an object that asyncronously loads a collection of objects into an IEnumerable. At the time I connect, the IEnumerable may have items already in it's collection, and may add items during the lifetime of the application that I need to be notified of as they occur. As an example, it could be a bank account containing a list of bank transactions.
The challenge is this. I want to combine the processing of the initial values in the IEnumerable with any new additions. They are currently two processes. I would like to eliminate the use of NotifyCollectionChanged entirely.
I can modify the backend holding the IEnumerable. It does not need to remain as an IEnumerable if a solution to this question exists otherwise.
I would suggest that the object should not expose a IEnumerable as that is for "cold observable values", where in your case you need something which can get additional items in future also.
The best way to model this would be to use ReplaySubject<T> instead of IEnumerable. Below is an example that demonstrate the situation similar of yours:
//Function to generate the subject with future values
public static ReplaySubject<int> GetSubject()
{
var r = new ReplaySubject<int>();
r.OnNext(1); r.OnNext(2); r.OnNext(3);
//Task to generate future values
Task.Factory.StartNew(() =>
{
while (true)
{
Thread.Sleep(3000);
r.OnNext(DateTime.Now.Second);
}
});
return r;
}
Consuming code:
var sub = GetSubject();
sub.Subscribe(Console.WriteLine);
Every time anyone subscribes to sub they will get all the values that have been published in the subject till now and as well as new values that this subject generates in future
You can use Defer/Replay Operator