How to use doOnNext, doOnSubscribe and doOnComplete? - rx-java2

New to RxJava2/RxAndroid and Android development, but am pretty familiar with Java.
However, I've ran into quite a roadblock when trying to "optimize" and be able to update the UI between a bunch of calls to the same resource.
My code is as follows:
private int batch = 0;
private int totalBatches = 0;
private List<ItemInfo> apiRetItems = new ArrayList<>();
private Observable<ItemInfo[]> apiGetItems(int[] ids) {
int batchSize = 100;
return Observable.create(emitter -> {
int[] idpart = new int[0];
for(int i = 0; i < ids.length; i += batchSize) {
batch++;
idpart = Arrays.copyOfRange(ids, i, Math.min(ids.length, i+batchSize));
ItemInfo[] items = client.items().get(idpart);
emitter.onNext(items);
}
emitter.onComplete();
}).doOnSubscribe( __ -> {
Log.d("GW2DB", "apiGetItems subscribed to with " + ids.length + " ids.");
totalBatches = (int)Math.ceil(ids.length / batchSize);
progressbarUpdate(0, totalBatches);
}).doOnNext(items -> {
Log.d("GW2DB", batch + " batches of " + totalBatches + " batches completed.");
progressbarUpdate(batch, totalBatches);
}).doOnComplete( () -> {
Log.d("GW2DB", "Fetching items completed!");
progressbarReset();
});
}
If I remove the doOnSubscribe, doOnNext and doOnComplete I get no errors in Android Studio, but if I use any of them I get Incompatible types. Required: Observable<[...].ItemInfo[]>. Found: Observable<java.lang.Object>
I'm using RxAndroid 2.1.1 and RxJava 2.2.16.
Any ideas?

Since you are adding a chain of method calls, the compiler is just unable to correctly guess the type for the generic parameter in Observable.create. You can set it explicitly using Observable.<ItemInfo[]>create(...).

Related

mongo query is hanging in filter of mono

I am facing mongo reactive repository hanging issue which cause the whole application hanging.
shipment.getItems().forEach(item -> {
return deliveryRepository.findById(item.getDeliveryNumber())
.filter(delivery -> Objects.isNull(delivery.getState()) || !delivery.getState().equals(TrackObjectState.DELIVERED))
.filter(delivery -> deliveryStatusShouldBeUpdatedToDelivered(delivery, shipment, gamMessage))
.flatMap(delivery -> {
delivery.setState(TrackObjectState.DELIVERED);
return deliveryRepository.save(delivery);
}).subscribe(delivery -> log.info("delivery: " + delivery.getDeliveryNumber() + " is updated to state delivered"));
});
inside method deliveryStatusShouldBeUpdatedToDelivered, I called a another service named incotermLocationService via blow code.
var alternativeLocations = incotermLocationService.getAlternativeUnLocationCodesByUnlocationCode(destinationLocation).blockOptional();
and this incotermLocationService code as following.
public Mono<Set<String>> getAlternativeUnLocationCodesByUnlocationCode(String unlocationCode) {
if (log.isDebugEnabled()) {
log.debug("alternative location get by un-location code is called with un-location code: " + unlocationCode);
}
return incotermLocationRepository.getAlternativeLocationsByUnLocationCode(unlocationCode)
.flatMap(incotermLocation -> Flux.fromIterable(incotermLocation.getUnLocationCodes()))
.map( unloCode -> { log.debug("unlocationCode: " + unloCode + " is returned"); return unloCode;})
.collect(Collectors.toSet());
}
but this incotermLocationRepository.getAlternativeLocationsByUnLocationCode() was in hanging for ever.
I checked this method which was called in other place works well. Then I take it out from the filter.
shipment.getItems().forEach(item -> {
var deliveryOptional = deliveryRepository.findById(item.getDeliveryNumber())
.filter(delivery -> Objects.isNull(delivery.getState()) || !delivery.getState().equals(TrackObjectState.DELIVERED))
.blockOptional();
if (deliveryOptional.isPresent() && deliveryStatusShouldBeUpdatedToDelivered(deliveryOptional.get(), shipment, gamMessage)) {
var delivery = deliveryOptional.get();
deliveryOptional.get().setState(TrackObjectState.DELIVERED);
deliveryRepository.save(delivery).subscribe(savedDelivery -> log.info("delivery: " + delivery.getDeliveryNumber() + " is updated to state delivered"));
}
});
Then repository was called and the whole logic works as expected.
Did u face this before that a reactive repository used in a filter method never triggered even it is called with block?

Flutter - How to use data from equal built classes?

I want to build an app for my pupil which generates tasks out of sentence blocks.
For example I created two classes, apple and pear, with nearly the same structure. They return a question built out of the sentence blocks which are defined in the classes. In both classes is a GenerateQuestion()-function for that.
Now I want to build some kind of overclass, which picks a random class of i.e. apple or pear and then returns the strings from the functions. The functions names are the same, but I can't figure out how to get data from a random choosen class. Hoping for help. Thanks in advance.
Update: Here is the code I wrote so far (I tried to translate it properly):
import 'dart:math';
int randomminmax1 = 0;
int randomminmax2 = 0;
int randomminmax3 = 0;
List classes = [apple, pear];
class overClass {
static pickClass(){
int randomClassItem = Random().nextInt(classes.length);
print(classes[randomClassItem]);
return classes[randomClassItem];
}
}
class apple {
static String giveQuestion() {
randomminmax1 = 2 + Random().nextInt(15 - 2);
randomminmax2 = randomminmax1 * (2+Random().nextInt(12 - 2));
randomminmax3 = 2 + Random().nextInt(30 - 2);
List value_1 = [" boxes", " bags", " bucket"];
List verbs = ["cost","have a price of", "are offered for"];
List value_2 = ["Euro"];
List questionWords = [""];
int randomIndexValue1 = Random().nextInt(value_1.length);
int randomIndexVerbs = Random().nextInt(verbs.length);
int randomIndexValue2 = Random().nextInt(value_2.length);
String value = randomminmax1.toString() + value_1[randomIndexValue1].toString() + " apples" + verbs[randomIndexVerbs].toString() + " " + randomminmax2.toString() + " " + value_2[randomIndexValue2].toString() + ".\n";
String question = "How much are " + randomminmax3.toString() + value_1[randomIndexValue1].toString() + "?\n";
return value + question;
}
static String giveAnswer(){
double result = (randomminmax2/randomminmax1)*randomminmax3;
return result.toStringAsFixed(2) + " Euro.";
}
}
class pear {
static String giveQuestion() {
randomminmax1 = 2 + Random().nextInt(15 - 2);
randomminmax2 = randomminmax1 * (2+Random().nextInt(12 - 2));
randomminmax3 = 2 + Random().nextInt(30 - 2);
List value_1 = [" boxes", " bags", " bucket"];
List verbs = ["cost","have a price of", "are offered for"];
List value_2 = ["Euro"];
List questionWords = [""];
int randomIndexValue1 = Random().nextInt(value_1.length);
int randomIndexVerbs = Random().nextInt(verbs.length);
int randomIndexValue2 = Random().nextInt(value_2.length);
String value = randomminmax1.toString() + value_1[randomIndexValue1].toString() + " pears" + verbs[randomIndexVerbs].toString() + " " + randomminmax2.toString() + " " + value_2[randomIndexValue2].toString() + ".\n";
String question = "How much are " + randomminmax3.toString() + value_1[randomIndexValue1].toString() + "?\n";
return value + question;
}
static String giveAnswer(){
double result = (randomminmax2/randomminmax1)*randomminmax3;
return result.toStringAsFixed(2) + " Euro.";
}
}
static String giveAnswer(){
double result = (randomminmax2/randomminmax1)*randomminmax3;
return result.toStringAsFixed(2) + " Euro.";
}
}
Can you try to create a superclass that all question classes will inherit and then get the subclasses and programmatically call functions. Try to see here
At least I managed to give my values directly from the classes into the list. But then I got problems with the int-variables, which were built wrong.
My "solution": I converted my classes into isolated flutter widgets, which works fine, except the problem that I'm not able to put the widgets into a list, from where they are picked randomly...but therefore I'll write a new post.
Thank you Moustapha for your help (the superclass idea sounds good, but way too hard to code for me) ;)!

Google/OR-Tools Get Duration And Distance

I'm trying to understand the solution call in the MVRP examples
I have two matrixes, duration and distance that have been returned via calls to google
My solution is based on distance but given that i have the data already returned i want to find the index associated with the duration.
unfortunately I'm not sure completely what is going on under the hood of the the Routing Calls so hoping for a simple fast answer for look up and what index to use
for simplicity sake I will show the google example rather than my code and highlight what im looking for:
public string PrintSolution()
{
// Inspect solution.
string ret = "";
long maxRouteDistance = 0;
for (int i = 0; i < _data.Drivers; ++i)
{
ret += $"Route for Vehicle {i}:";
ret += Environment.NewLine;
long routeDistance = 0;
var index = _routing.Start(i);
while (_routing.IsEnd(index) == false)
{
ret += $"{_manager.IndexToNode((int) index)} -> ";
var previousIndex = index;
index = _solution.Value(_routing.NextVar(index));
long legDistance = _routing.GetArcCostForVehicle(previousIndex, index, i);
//LOOKING FOR
//long legDuration = ??? what index am is using here to find in my duration matrix which is built the same as indexes as distance
ret += " leg distance: " + legDistance;
routeDistance += legDistance;
}
ret += $"{_manager.IndexToNode((int) index)}";
ret += Environment.NewLine;
ret += $"Distance of the route: {routeDistance}m";
ret += Environment.NewLine;
ret += Environment.NewLine;
maxRouteDistance = Math.Max(routeDistance, maxRouteDistance);
}
ret += $"Maximum distance of the routes: {maxRouteDistance}m";
ret += Environment.NewLine;
return ret;
}
#Mizux
disclaimer: This is a simplification but should help you to understand.
In OR-Tools Routing there is a primal "hidden" dimension without name but you can retrieve the cost using RoutingModel::GetArcCostForVehicle()
For any "regular" dimension you can get inspect the CumulVar at each node.
e.g. supposing you have created two dimensions using RoutingModel::AddDimension() whose name were "Distance" and "Duration".
note: CumulVar is an accumulator so if you want the "arc cost" you'll need something like this dim.CumulVar(next_index) - dim.CumulVar(index)
Then in you PrintFunction you can use:
public string PrintSolution()
{
...
RoutingDimension distanceDimension = routing.GetMutableDimension("Distance");
RoutingDimension durationDimension = routing.GetMutableDimension("Duration");
for (int i = 0; i < _manager.getNumberOfVehicles(); ++i)
{
while (_routing.IsEnd(index) == false)
{
...
IntVar distanceVar = distanceDimension.CumulVar(index);
IntVar durationVar = durationDimension.CumulVar(index);
long distance = _solution.Value(distanceVar);
long duration = _solution.Value(durationVar);
...
}
}
}

Access non static function from static function

Here is some insight: I am working with UnityScript in Unity 4.6.3. I have one script called Pause.js and it contains this function:
function fadeMusicOut () {
while (audio.volume >= 0.005) {
yield WaitForSeconds(0.1);
Debug.Log("Loop Entered: " + audio.volume);
audio.volume = (audio.volume - 0.015);
}
Another script GameManager.js has this function:
static function Score (wallName : String) {
if (wallName == "rightWall") {
playerScore01 += 1;
}
else {
playerScore02 += 1;
}
if (playerScore01 == SettingsBack.scoreLimit || playerScore02 == SettingsBack.scoreLimit)
{
startParticles = 1;
SettingsBack.gameOver = 1;
BallControl.fadeSound = 1;
yield WaitForSeconds(4);
Camera.main.SendMessage("fadeOut");
Pause.fadeMusic = 1;
SettingsBack.soundVolume = 0;
yield WaitForSeconds(2);
playerScore01 = 0;
playerScore02 = 0;
SettingsBack.soundVolume = oldSoundVol;
Application.LoadLevel("_Menu");
}
}
So pretty much I want to call the fadeMusicOut() function from static function Score, but it will not let me because it says it needs an instance of that object.
The Pause.js script is not attached to any game objects, but it is attached to 2 buttons that call their specific functions. The GameManager.js script is attached to an object called GM. So how can I go about calling fadeMusicOut() from the Score function?
I have tried setting new vars that import the game object but still no luck. I tried making fadeMusicOut() a static function, but it creates many errors.
Any help at all is appreciated.

ADO.net Question - How can I update a column in a Row of a DataTable with RowChanged without triggering infinite loop?

How can I update the column value (programmatically) in a Row of a DataTable via use of the RowChanged event, without triggering infinite loop? (which I currently get)
Note I do not want to use the DataColumn.Expression property.
For example the following gives me a recursive loop and stack overflow error:
DataColumn dc = new DataColumn("OverallSize", typeof(long));
DT_Webfiles.Columns.Add(dc);
DT_Webfiles.RowChanged += new DataRowChangeEventHandler(DT_Row_Changed);
private static void DT_Row_Changed(object sender, DataRowChangeEventArgs e)
{
Console.Out.WriteLine("DT_Row_Changed - Size = " + e.Row["OverallSize"]);
e.Row["OverallSize"] = e.Row["OverallSize"] ?? 0;
e.Row["OverallSize"] = (long)e.Row["OverallSize"] + 1;
}
thanks
PS. In fact using the RowChanging event (rather than RowChanged) makes sense to me (i.e. change the value before it saves so to speak) however when I try this I get a "Cannot change a proposed value in the RowChanging event" at the following line in the handler:
e.Row["OverallSize"] = e.Row["OverallSize"] ?? 0;
You could unsubscribe when within the event handler, though that would make your code not thread-safe.
DataColumn dc = new DataColumn("OverallSize", typeof(long));
DT_Webfiles.Columns.Add(dc);
DT_Webfiles.RowChanged += new DataRowChangeEventHandler(DT_Row_Changed);
private static void DT_Row_Changed(object sender, DataRowChangeEventArgs e)
{
e.RowChanged -= new DataRowChangeEventHandler(DT_Row_Changed);
Console.Out.WriteLine("DT_Row_Changed - Size = " + e.Row["OverallSize"]);
e.Row["OverallSize"] = e.Row["OverallSize"] ?? 0;
e.Row["OverallSize"] = (long)e.Row["OverallSize"] + 1;
e.RowChanged += new DataRowChangeEventHandler(DT_Row_Changed);
}
Try with this
e.Row.Table.RowChanged -= new DataRowChangeEventHandler(DT_Row_Changed);
And
e.Row.Table.RowChanged += new DataRowChangeEventHandler(DT_Row_Changed);