I am working with Firebase so I have a lot of return types of type ApiFuture<A>. I'd like to turn them into a Task[A] to work with ZIO effects.
We can create a method to convert all of them using Typeclasses:
trait EffectUtils[F[_]] {
def toEffect[A](a: F[A]): Task[A]
}
object EffectUtils {
implicit val apiFuture: EffectUtils[ApiFuture] = new EffectUtils[ApiFuture] {
override def toEffect[A](a: ApiFuture[A]): Task[A] = Task.effectAsync[A]( cb =>
ApiFutures.addCallback(a, new ApiFutureCallback[A] {
override def onFailure(t: Throwable): Unit = cb(Task.fail(t))
override def onSuccess(result: A): Unit = cb(Task.succeed(result))
})
)
}
implicit class ApiFutureOps[A](f: ApiFuture[A]) {
def toEffect(implicit instance: EffectUtils[ApiFuture]) = instance.toEffect(f)
}
}
Now, when we make an API request and want to convert the result to a ZIO type, it's easy:
import EffectUtils._
object App {
// calling a Firebase function
val record: Task[UserRecord] = firebase.getInstance().auth().getUserByEmailAsync(email).toEffect
Related
I have a ZIO that looks like this:
ZIO[transactor.Transactor[Task], Serializable, String]
and I need to assert the String, that is in that ZIO with another plain String.
So my question is:
How can I assert the plain String, with the String in the ZIO, or
can I lift the String into that same ZIO, to assert it with this one:
ZIO[transactor.Transactor[Task], Serializable, String]
I´m working with ZIO-Test as my testing framework.
I got this based on the rock the jvm zio course. Important things are highlighted in the comments
package com.w33b
import zio.test._
import zio._
object ZIOAssert extends ZIOSpecDefault {
class ATask
abstract class Transact[ATask] {
def get(): String
def put(ATask: ATask): ATask
}
// This is the mock service that we will use to create a ZLayer
val mockTransact = ZIO.succeed(new Transact[ATask] {
override def get(): String = "hello"
override def put(aTask: ATask): ATask = new ATask
})
// This is the method we are testing and we need a service (Zlayer) associated with it.
// We then use the service to invoke a method to get our return value
def methodUnderTest: ZIO[Transact[ATask], Serializable, String] = {
for {
trans <- ZIO.service[Transact[ATask]]
tVal = trans.get()
} yield tVal
}
def spec = suite("Let's test that ZIO lift")(
test("lets test that lift") {
assertZIO(methodUnderTest)(Assertion.equalTo("hello"))
}
).provide(ZLayer.fromZIO(mockTransact)) // Important to provide the layer or we can't test
}
with ZIO 2.x
val spec = suite("tetst")(
test("whatever"){
val effect: ZIO[transactor.Transactor[Task], Serializable, String] = ???
val expected: String = ???
for {
value <- effect
} yield assertTrue(value == expected)
}
)
In general, you just create here a ZIO with the assertion in the success channel.
I am trying to get a class to have a property bound to another class's list property, where the 1st property is derived from a summarizing calculation over the objects in the list. The code below is a simplified version of my production code. (The production code is doing a summary over DateTime objects -- the essential part of the code below is the binding between a list and an object property (here, it is a String for simplicity).)
I have tried various things. One approach was using addListener on the list in the Summary class below but I was running into weird bugs with the listener callback making updates on the Summary object. After doing a bunch of reading I think that a binding between the summary string and the list is more appropriate but I don't know exactly how to hook up the binding to the property?
package com.example.demo.view
import javafx.beans.Observable
import javafx.beans.binding.StringBinding
import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleListProperty
import javafx.beans.property.SimpleStringProperty
import javafx.collections.FXCollections
import tornadofx.View
import tornadofx.button
import tornadofx.label
import tornadofx.vbox
class Thing(x: Int) {
val xProperty = SimpleIntegerProperty(x)
val yProperty = SimpleStringProperty("xyz")
}
class Collection {
private var things = FXCollections.observableList(mutableListOf<Thing>()) {
arrayOf<Observable>(it.xProperty)
}
val thingsProperty = SimpleListProperty<Thing>(things)
fun addThing(thing: Thing) {
things.add(thing)
}
}
class Summary(var collection: Collection) {
val summaryBinding = object : StringBinding() {
// The real code is more practical but
// this is just a minimal example.
override fun computeValue(): String {
val sum = collection.thingsProperty.value
.map { it.xProperty.value }
.fold(0, { total, next -> total + next })
return "There are $sum things."
}
}
// How to make this property update when collection changes?
val summaryProperty = SimpleStringProperty("There are ? things.")
}
class MainView : View() {
val summary = Summary(Collection())
override val root = vbox {
label(summary.summaryProperty)
button("Add Thing") {
summary.collection.addThing(Thing(5))
}
}
}
Keep in mind that I made this answer based on your minimal example:
class Thing(x: Int) {
val xProperty = SimpleIntegerProperty(x)
var x by xProperty
val yProperty = SimpleStringProperty("xyz")
var y by yProperty
}
class MainView : View() {
val things = FXCollections.observableList(mutableListOf<Thing>()) {
arrayOf<Observable>(it.xProperty)
}
val thingsProperty = SimpleListProperty<Thing>(things)
val totalBinding = integerBinding(listProperty) {
value.map { it.x }.fold(0, { total, next -> total + next })
}
val phraseBinding = stringBinding(totalBinding) { "There are $value things." }
override val root = vbox {
label(phraseBinding)
button("Add Thing") {
action {
list.add(Thing(5))
}
}
}
}
I removed your other classes because I didn't see a reason for them based on the example. If the collection class has more functionality than holding a list property in your real project, then add just add it back in. If not, then there's no reason to give a list its own class. The summary class is really just two bindings (or one if you have no need to separate the total from the phrase). I don't see the need to give them their own class either unless you plan on using them in multiple views.
I think your biggest problem is that you didn't wrap your button's action in action {}. So your code just added a Thing(5) on init and had no action set.
P.S. The var x by xProperty stuff will only work if you import tornadofx.* for that file.
I've currently got a simple Value Converter which uses momentjs to convert Dates to strings:
export class MomentValueConverter {
public toView(value: Date, format: string): string {
return moment(value).format(format);
}
}
However, wherever I use it I end up having to combine it with the aurelia-translation-signal so that its updated if the user changes the current language.
${fileSaved | moment:'ll LTS' & signal:'aurelia-translation-signal'}
How do I instead create a Binding Behavior that automatically takes care of the signalling from aurelia-translation-signal?
Then I could use it like:
${fileSaved & moment:'ll LTS'}
There is a good example in aurelia-i18n library, https://github.com/aurelia/i18n/blob/master/src/t.js#L89-L122
import {ValueConverter} from 'aurelia-binding';
import {SignalBindingBehavior} from 'aurelia-templating-resources';
export class TBindingBehavior {
static inject = [SignalBindingBehavior];
constructor(signalBindingBehavior) {
this.signalBindingBehavior = signalBindingBehavior;
}
bind(binding, source) {
// bind the signal behavior
this.signalBindingBehavior.bind(binding, source, 'aurelia-translation-signal');
// rewrite the expression to use the TValueConverter.
// pass through any args to the binding behavior to the TValueConverter
let sourceExpression = binding.sourceExpression;
// do create the sourceExpression only once
if (sourceExpression.rewritten) {
return;
}
sourceExpression.rewritten = true;
let expression = sourceExpression.expression;
sourceExpression.expression = new ValueConverter(
expression,
't',
sourceExpression.args,
[expression, ...sourceExpression.args]);
}
unbind(binding, source) {
// unbind the signal behavior
this.signalBindingBehavior.unbind(binding, source);
}
}
UPDATE: Signals are internally supported by value converters already http://aurelia.io/docs/binding/value-converters#signalable-value-converters
import {signalBindings} from 'aurelia-framework';
signalBindings('locale-changed');
export class FlightTimeValueConverter {
signals = ['locale-changed'];
toView(date) {
return date.toLocaleString(window.currentLocale);
}
}
I'm having trouble figuring out the problem that flow is complaining about. I'm trying to allow the implementation of an API be changeable by storing the implementation class, then later instantiating it, however, flow complains when I call new this.implKlass saying that "Constructor cannot be called on object type". What is flow trying to tell me, and what am I conceptually missing about how flow works?
Example code below, and flow try code here
/* #flow */
type ApiT = {
fnA(): Promise<*>;
}
// An implementation of the API
class Impl {
async fnA(): Promise<*> { return 1; }
}
class DoThings {
implKlass: ApiT;
constructor(klass) {
this.implKlass = klass;
}
callA() {
const Klass = this.implKlass;
const inst = new Klass();
return inst.fnA();
}
}
new DoThings(Impl).callA();
Example output:
18: const inst = new Klass();
^ constructor call. Constructor cannot be called on
18: const inst = new Klass();
^ object type
13: constructor(klass: ApiT) {
^ property `fnA`. Property not found in
23: new DoThings(Impl).callA();
^ statics of Impl
With a small modification this works.
class DoThings {
implKlass: Class<ApiT>;
constructor(klass) {
this.implKlass = klass;
}
callA() {
const Klass = this.implKlass;
const inst = new Klass();
return inst.fnA();
}
}
The bug was you were writing ApiT instead of Class<ApiT>. ApiT would be an instance of a class, while Class<ApiT> is the class itself.
Try flow link
ApiT describes an object type, not a class type. An instance of the Impl class satisfies the ApiT type, but the class Impl itself does not. You cannot call Impl.fnA(), for example.
I'm not sure if there is any way to pass around constructors like this. However you can accomplish basically the same thing by using a factory function:
type ApiT = {
fnA(): Promise<*>;
}
type ApiTFactory = () => ApiT;
class Impl {
async fnA(): Promise<*> { return 1; }
}
class DoThings {
factory: ApiTFactory;
constructor(factory: ApiTFactory) {
this.factory = factory;
}
callA() {
const factory = this.factory;
const inst = factory();
return inst.fnA();
}
}
new DoThings(() => new Impl()).callA();
tryflow link
To make debug-time introspection into classes easy, I'd like to make a generic toString method in the base class for the objects in question. As it's not performance critical code, I'd like to use Reflection to print out field name/value pairs ("x=1, y=2" etc).
Is there an easy way to do this? I tried several potential solutions, and ran up against security access issues, etc.
To be clear, the toString() method in the base class should reflectively iterate over public vals in any classes that inherit from it, as well as any traits that are mixed in.
Example:
override def toString() = {
getClass().getDeclaredFields().map { field:Field =>
field.setAccessible(true)
field.getName() + ": " + field.getType() + " = " + field.get(this).toString()
}.deepMkString("\n")
}
Uses Java Reflection API, so don't forget to import java.lang.reflect._
Also, you may need to catch IllegalAccessException on the field.get(this) calls in some scenarios, but this is just meant as a starting point.
Are you aware the Scala case classes get these compiler-generated methods:
toString(): String
equals(other: Any): Boolean
hashCode: Int
They also get companion objects for "new-less" constructors and pattern matching.
The generated toString() is pretty much like the one you describe.
import util._ // For Scala 2.8.x NameTransformer
import scala.tools.nsc.util._ // For Scala 2.7.x NameTransformer
/**
* Repeatedly run `f` until it returns None, and assemble results in a Stream.
*/
def unfold[A](a: A, f: A => Option[A]): Stream[A] = {
Stream.cons(a, f(a).map(unfold(_, f)).getOrElse(Stream.empty))
}
def get[T](f: java.lang.reflect.Field, a: AnyRef): T = {
f.setAccessible(true)
f.get(a).asInstanceOf[T]
}
/**
* #return None if t is null, Some(t) otherwise.
*/
def optNull[T <: AnyRef](t: T): Option[T] = if (t eq null) None else Some(t)
/**
* #return a Stream starting with the class c and continuing with its superclasses.
*/
def classAndSuperClasses(c: Class[_]): Stream[Class[_]] = unfold[Class[_]](c, (c) => optNull(c.getSuperclass))
def showReflect(a: AnyRef): String = {
val fields = classAndSuperClasses(a.getClass).flatMap(_.getDeclaredFields).filter(!_.isSynthetic)
fields.map((f) => NameTransformer.decode(f.getName) + "=" + get(f, a)).mkString(",")
}
// TEST
trait T {
val t1 = "t1"
}
class Base(val foo: String, val ?? : Int) {
}
class Derived(val d: Int) extends Base("foo", 1) with T
assert(showReflect(new Derived(1)) == "t1=t1,d=1,??=1,foo=foo")
Scala doesn't generate any public fields. They're all going to be private. The accessor methods are what will be public, reflect upon those. Given a class like:
class A {
var x = 5
}
The generated bytecode looks like:
private int x;
public void x_$eq(int);
public int x();