How to get data from Flowable to another Flowable? - asynchronous

I have 2 Flowables (one which is giving me VelocityNed items, and other which I written to consume items from first one); the thing is I don't know how to make the second one right, since I still not feel sure with RxJava
my Flowable code:
private Flowable<Float> getIAS(Flowable<VelocityNed> velocityNed) {
Flowable<Float> flowable = Flowable.create(emitter->{
velocityNed.subscribeWith(new DisposableSubscriber<VelocityNed>() {
#Override public void onNext(VelocityNed v) {
float valueToEmit = (float)Math.sqrt(Math.pow(v.getDownMS(),2)+Math.pow(v.getEastMS(),2)+Math.pow(v.getNorthMS(),2));
//how to emit this
}
#Override public void onError(Throwable t) {
t.printStackTrace();
}
#Override public void onComplete() {
emitter.onComplete();
this.dispose();
}
});
}, BackpressureStrategy.BUFFER);
return flowable;
}

You don't need to create a Flowable manually just to transform the emissions. You can do originalFlowable.map(element -> { transform element however you want }).
In your case it would be something like:
Flowable<Float> flowable = velocityNed.map(v -> {
(float)Math.sqrt(Math.pow(v.getDownMS(),2)+Math.pow(v.getEastMS(),2)+Math.pow(v.getNorthMS(),2));
})

Related

in dart, is there any way to limit the key in some special strings

i search many place, did not find any solution.
so the question is.
i want a map in dart like this
var Map<String, String> data;
it will be a params init and passed in other place. but when pass the params, i want to limit the key in map only accept some special strings. like 'someA', 'someB'.
so,when call the function it like this.
functionA({'someA': 'xxxx', 'someB': 'xxxx'})
no other keys.
and also when i call the function i can just type some word and the IDE will show suggestion for me to select the key.
the all code like this (can not run).
var List<String> keyList = ['someA', 'someB'];
class Abc {
functionA({Map<valueOf keyList, String> data) {
}
}
Abc().functionA({'someA': 'xxxx', 'someB': 'xxxx'});
You can provide your own Map implementation (deriving from DelegatingMap from package:collection would make it a lot easier) and then override operator []= to throw if the supplied key should not be allowed. For example:
import 'package:collection/collection.dart';
/// A [Map] that allows only certain keys.
class LimitedMap<K, V> extends DelegatingMap<K, V> {
LimitedMap({Iterable<K> allowedKeys})
: allowedKeys = <K>{...allowedKeys},
super(<K, V>{});
final Set<K> allowedKeys;
/// Throws an exception if [key] is not allowed.
void _checkKey(K key) {
if (!allowedKeys.contains(key)) {
throw Exception('Invalid key: $key');
}
}
#override
void addAll(Map<K, V> other) => addEntries(other.entries);
#override
void addEntries(Iterable<MapEntry<K, V>> entries) {
for (var entry in entries) {
this[entry.key] = entry.value;
}
}
#override
V putIfAbsent(K key, V Function() ifAbsent) {
_checkKey(key);
return super.putIfAbsent(key, ifAbsent);
}
#override
V update(K key, V Function(V) update, {V Function() ifAbsent}) {
_checkKey(key);
return super.update(key, update, ifAbsent: ifAbsent);
}
#override
void operator []=(K key, V value) {
_checkKey(key);
super[key] = value;
}
}
class MyMap extends LimitedMap<String, String> {
MyMap([Map<String, String> initialMap])
: super(allowedKeys: {'foo', 'bar', 'baz'}) {
if (initialMap != null) {
addAll(initialMap);
}
}
}
Alternatively, if your keys are fixed, it'd be better to just make them properties on a custom class, and then you also would get the IDE autocompletion behavior that you want.

TornadoFX with TestFX close the View after every TestCase

I am trying to test a basic loginscreen (created using tornadofx) with the testfx framework.
I have added 3 test cases which runs fine but the problem is they use the previous stage rather than creating a new one. I want the testcases to run independently.
I am testing a View() and not an App(). If I use MyMainApp().start(stage) and then MyMainApp().stop(), I get the required behaviour.
But how to do this for Views and Fragments.
Below is the code:
class LoginScreenFeatureTest : ApplicationTest() {
override fun init() {
FxToolkit.registerStage { Stage() }
}
override fun start(stage: Stage) {
LoginScreen().openWindow()
//MyMainApp().start(stage)
}
override fun stop() {
FxToolkit.cleanupStages()
//FxToolkit.toolkitContext().registeredStage.close()
//MyMainApp().stop()
}
#Test fun should_contain_button() {
// expect:
verifyThat("#submitBut", hasText("SUBMIT"))
}
#Test fun should_click_on_button_and_pass_login() {
//init
//Why do I always need to erase text. I want a new stage for every test case.
clickOn("#username").eraseText(10).write("validUser")
clickOn("#password").eraseText(10).write("validPwd")
clickOn("#orgId").eraseText(10).write("validOrg")
// when:
clickOn("#submitBut")
// then:
//verify success
}
#Test fun should_click_on_button_and_fail_login() {
//init
clickOn("#username").eraseText(10).write("anyuser")
clickOn("#password").eraseText(10).write("anypwd")
clickOn("#orgId").eraseText(10).write("anyorg")
// when:
clickOn("#submitBut")
// then:
//verify fail
}
}
You can add property which you can edit at any time at you App() class.
class MyMainApp: App() {
override val primaryView: KClass<out View> = primaryViewMyApp
companion object {
var primaryViewMyApp: KClass<out View> = MyMainAppView::class
}
init {
importStylesheet(<your stylesheet>)
}
override fun start(stage: Stage) {
super.start(stage)
}
override fun stop() {
super.stop()
}
}
and in the test you can than use any view you want to use. I didnt try to implement something for Fragment so far...
override fun init() {
FxToolkit.registerStage { Stage() }
}
override fun start(stage: Stage) {
MyMainApp.primaryViewGoApp = <your view>::class
MyMainApp().start(stage)
}
override fun stop() {
FxToolkit.cleanupStages()
MyMainApp().stop()
}

Realm.firstFirstAsync().asObservable() isn't consistently working with RxJava.switchIfEmpty

I am trying to create function which reads a object from realm and emit an empty observable if the object isn't found. The code below works to some degree because I can stop it with the debugger and see it hit the Observable.empty():
fun readFromRealm(id: String): Observable<Player> {
return realm.where(Player::class.java)
.equalTo("id", id)
.findFirstAsync()
.asObservable<Player>()
.filter { it.isLoaded }
.flatMap {
if (it.isValid)
Observable.just(it)
else
Observable.empty()
}
}
But when I try to use a switchIfEmpty on the Observable the code never emits defaultPlayer when it is not found in realm.
return readFromRealm(playerId)
.take(1)
.map{ // do something with emitted observable }
.switchIfEmpty(Observable.just(defaultPlayer)) // use this if no player found
The strange thing is that if I update the original method to include a first() prior to the flatMap :
fun readFromRealm(id: String): Observable<Player> {
return realm.where(Player::class.java)
.equalTo("id", id)
.findFirstAsync()
.asObservable<Player>()
.filter { it.isLoaded }
.first() // add first
.flatMap {
if (it.isValid)
Observable.just(it)
else
Observable.empty()
}
}
Everything starts working as expected, but I believe this version will kill auto updating because it will only capture the first result emitted after the filter.
I'm still trying to grok Realm and Rx so I'm probably doing something dumb.
EDIT: I have created a sample project which highlights the issue I'm seeing - https://github.com/donaldlittlepie/realm-async-issue
For reasons I don't totally understand. If you move take(1) just above the
flatMap and below the filter it should work correctly:
realm.where(Dog.class)
.equalTo("id", 0L)
.findFirstAsync()
.asObservable()
.cast(Dog.class)
.filter(new Func1<RealmObject, Boolean>() {
#Override
public Boolean call(RealmObject realmObject) {
return realmObject.isLoaded();
}
})
.take(1) // <== here
.flatMap(new Func1<Dog, Observable<Dog>>() {
#Override
public Observable<Dog> call(Dog realmObject) {
if (realmObject.isValid()) {
return Observable.just(realmObject);
} else {
return Observable.empty();
}
}
})
.map(new Func1<Dog, Dog>() {
#Override
public Dog call(Dog dog) {
dog.setName("mapped " + dog.getName());
return dog;
}
})
.switchIfEmpty(Observable.just(createDefaultDog()))
.subscribe(new Action1<Dog>() {
#Override
public void call(Dog dog) {
textView.setText(dog.getName());
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
textView.setText(throwable.toString());
}
});
My best guess is that before, flatMap was called repeatedly, returning Observable.empty() multiple times. Perhaps that effects the Observable chain in some unexpected way.

Get Image from File Storage [Backendless]

My users upload some images to the FileStorage at Backendless.
This is the upload sequence:
Backendless.Files.Android.upload(image1_scaled, Bitmap.CompressFormat.PNG,
100, "profileImage", "images", new AsyncCallback<BackendlessFile>() {
#Override
public void handleResponse(BackendlessFile response) {
fileMapping.profile_url = response.getFileURL();
Backendless.Data.of(FileMapping.class).save(fileMapping,
new AsyncCallback<FileMapping>() {
#Override
public void handleResponse(FileMapping response) {
toast_error("Image stored");
}
#Override
public void handleFault(BackendlessFault fault) {
System.out.println("ERROR" + fault.getCode());
}
});
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
And that works flawlessly. Now I need to fetch back the image with the API to display it.
So I need to make a BackendlessCollection<FileMapping> userFiles = Backendless.Data.of(FileMapping.class) call to receive the URL back from that table. And then supposedly do a httpRequest with the url to get back the byte data.
What I can't work out is what sort of .find method to use? Do I .findById() ? And if so, what ID do I use? The "path", "name" ,"table" etc?
Could anyone show an example fitting my case here, with a table storing the url's and such?
Thanks.
You'd this something like this (showing sync call for simplicity, but make sure to change it to Async on Android):
BackendlessCollection<FileMapping> fileMappings;
fileMappings = Backendless.Data.of( FileMapping.class ).find();
Iterator<FileMapping> iterator = fileMappings.getCurrentPage().iterator();
while( iterator.hasNext() )
{
FileMapping fileMapping = iterator.next();
Log.i( "MyApp", "file URL is " + fileMapping.profile_url );
}

WebFlowTestCase registerFlow() multiple flows possible?

Hi I have a WebFlowTestCase and is working fine but I ran into a prob when I need to test another flow that is in the same controller ( groovy).
The is what my controller looks like:
class MyController {
def someService
def dateHelper = new DateHelper()
def index = {... }
def myCreateFlow = {
start{}
createCase{}
finishCancel{
}
def myViewFlow = {...}
def myEditFlow = {...}
}
I have managed to successfully create the test for myCreateFlow like this:
class MyControllerTest extends WebFlowTestCase {
def myController = new MyController();
#Override
public Object getFlow() {
// TODO Auto-generated method stub
return myController.myCreateFlow
}
protected void setUp() {
super.setUp()
}
protected void tearDown() {
super.tearDown()
}
void testmyCreateFlow()
{
...
}
}
my question is how about the myEditFlow and myViewFlow? How do I register or use it when the getFlow() returns only the myCreateFlow? Is there I way I can use all of them in one webflowtest with out creating a new webflowtestclass? Or is there a way I can put it inside getflow with some switch/if else method something like:
#Override
public Object getFlow() {
// TODO Auto-generated method stub
if condition
return myController.myCreateFlow
else return myController.myEditFlow
}
coz when i tried creating a testmyEditFlow() I get the error below and I know that it is because the get flow only returns the myCreateFlow. At least that is how I perceive the test error msg.
Cannot find state with id 'myEditFlow' in flow 'test' -- Known state
ids are 'array['start', 'createCase'... 'finishCancel']'
You could register your other flows in a setUp method as follows:
protected void setUp() {
super.setUp()
registerFlow("myController/myEdit", myController.myEditFlow)
registerFlow("myController/myView", myController.myViewFlow)
}

Resources