Mobx and observing array changes from third-party library - mobx

I have a class with #observable properties and can react to local observable changes OK. The class also makes use of a third-party library that has a method OrderBookSnapshot() which returns a snapshot of the most recent array, but is not observable. I gather that I cannot assign non-observable arrays to the observable property. But is there a way to observe non-observable arrays from another library without making that library observable itself?
export class MyOrderBook {
#observable
private offerBook: any[]
private cmeClient // third-party class
constructor(symbol: string[]) {
this.offerBook = []
this.cmeClient = new cmeClient.OrderBook(symbol[0])
}
// Calls third-party method and returns updated array
UpdateOrderbookSync() {
// This is not observable
this.offerBook = this.cmeClient.OrderBookSnapshot()
}
}

Adding potential solution to my answer. The #action.bound decorator appears to give the desired result. Though it is not clear if this is the best way to update an observable array, since most of the array is unchanged.
#action.bound
UpdateOrderbookSync() {
// This is not observable
this.offerBook = this.cmeClient.OrderBookSnapshot()
}

Related

Difference between get() and by lazy

Having a room Dao as below,
#Dao
public abstract class AccountDao {
#Query("SELECT * FROM Account LIMIT 0,1")
public abstract Account readAccount();
}
is there any differences between get() and by lazy in the sample below?
open val account: LiveData<Account>
get() = accountDao.readAccount()
open val account: LiveData<Account> by lazy { accountDao.readAccount() }
The difference is in how many times the function body (accountDao.readAccount()) will be executed.
The lazy delegate will execute the lambda one single time the first time it is accessed and remember the result. If it is called again, that cached result is returned.
On the other hand, defining the getter (get()) will execute the function body every time, returning a new result every time.
For example, let's suppose we have a class called Foo with both a getter and a lazy value:
class Foo {
val getterVal: String
get() = System.nanoTime().toString()
val lazyVal: String by lazy { System.nanoTime().toString() }
}
And then use it:
fun main() {
with(Foo()) {
repeat(2) {
println("Getter: $getterVal")
println("Lazy: $lazyVal")
}
}
}
For me, this prints:
Getter: 1288398235509938
Lazy: 1288398235835179
Getter: 1288398235900254
Lazy: 1288398235835179
And we can see that the getter returns a newly calculated value each time, and the lazy version returns the same cached value.
In addition to Todd's answer:
Yes, there is a difference for LiveData objects as well. Every call of accountDao.readAccount() will result in a different LiveData object. And it does matter, despite the fact that all of the returned LiveData will get updated on every change in the Account entity. Let me explain on these examples:
by lazy
As Todd mentioned, the block inside the lazy delegate will be executed once, at the first time that the account property is accessed, the result will be cached and returned on every next access. So in this case a single one LiveData<Account> object is created. The bytecode generated by Kotlin to achieve this is equivalent to this in Java:
public class Activity {
private Lazy account$delegate
public LiveData<Account> getAccount() {
return account$delegate.getValue();
}
}
get()
By creating a custom account property's getter and calling accountDao.readAccount() inside, you will end up with different LiveData<Account> objects on every access of the account property. Once more, bytecode generated for this case in Kotlin in Java is more or less this:
public class Activity {
public LiveData<Account> getAccount() {
return accountDao.readAccount();
}
}
So you can see, using a lazy property results in generating a backing field for this property, while using a custom getter creates a wrapper method for the accountDao.readAccount() call.
It's up to your needs which approach you should use. I'd say that if you have to obtain the LiveData only once, you should go with get(), because a backing field is needless in that case. However if you're going to access the LiveData in multiple places in your code, maybe a better approach would be to use by lazy and create it just once.

Vue.js: using a data object's method in inline event handler

I have a Vue(2.5+) component where I'm setting a data property to a new Foo object. Using foo.bar() in the click handler calls the method correctly, but throws Uncaught TypeError: cannot set property 'someVariable' of null when trying to modify properties inside the Foo class. Setting it up so that Foo is an object literal instead of a class also does not resolve the error.
I suspect something weird is happening with this, between the component and the class?
Vue component
import Foo from './foo.js'
export default {
template: `<div #click="foo.bar"></div>`,
data() {
return {
foo: new Foo()
}
},
created() {
console.log(foo); // foo is not null here
}
}
Foo class
export default class Foo
{
constructor()
{
this.someVariable = 0;
}
bar(e)
{
// modify this.someVariable
}
}
but if I change the vue component to reference the external method through it's own "methods" property, it works.
Vue component (working)
import Foo from './foo.js'
export default {
template: `<div #click="bar"></div>`,
data() {
return {
foo: new Foo()
}
},
methods: {
bar(e) {
this.foo.bar(e);
}
}
}
As said in the comments, foo.bar without any context attached to it :
In JS functions are objects, just like any object they have their own this "pointer".
In the evaluation of their body, this is bound to a specific object referred to as context which is either the default context (automatically set) or user defined (manually set).
Inheritance in JS is achieved through a prototype chain and methods should be defined on/attached to the class's prototype. Because of this, when you call foo.bar() :
You are in a method call context, therefore foo will be bound to the method
bar is searched on the object first then in the prototype chain
But methods behave just like any other property : when you do foo.bar you get a reference to the actual method which is an unbound function (default behavior for methods, since it is bound when called on an object).
Therefore, what you really need to do in this situation is foo.bar.bind(foo).
I would also suggest taking a quick look into this ES6 proposal for a bind operator and its implementation as a Babel plugin which allows nice things like passing ::foo.bar instead of foo.bar.bind(foo)

React Native: Best way to pass array of objects to a function in a Component

I have a component which has two functions in it. One function returns an array of objects while the other receives it as a parameter. Both the functions being in the same component.
Example Code:
export default class Test extends Component {
func1 () {
return arrayofobj
}
param = this.func1();
func2 (param) {
param.id
}
}
So, my question is. How can we pass and access the array of objects to "func2" i.e. param.id
Also, I do not want to use state or props in this case.
You do not really understand what a class and component are. Try to learn about it here: https://facebook.github.io/react/docs/react-component.html
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes

how uses "uses" attribute in Ext.define?

How use "uses" attribute in Ext.define ?
Please example
I could find on the topic only Sencha Ext.define Uses vs Requires
Ext.define('Mother', {
uses: ['Child'],
giveBirth: function() {
// This code might, or might not work:
// return new Child();
// Instead use Ext.create() to load the class at the spot if not loaded already:
return Ext.create('Child');
}
});
List of optional classes to load together with this class. These aren't neccessarily loaded before this class is created, but are guaranteed to be available before Ext.onReady listeners are invoked.

Ext.Create returning classes that are already instantiated

I'm making use of the extjs class objects through Ext.define (... and Ext.create (.... When I have multiple instances of classes stored within another class I'm seeing some strange behavior: the classes are not unique and it looks like Ext.create is returning my previous instantiation.
Checkout the JSFiddle of my problem here. Make sure you view the console log in your browser to see the output and weirdness.
You're setting an array in Ext.define. That implies that you're setting into the object's prototype which is shared among all instances of a class. Therefore this is not an unexpected behaviour. Create the array within the constructor, like here:
Ext.define ('Sunglasses', {
brand : '',
constructor : function (args) {
this.lenses = [];
this.brand = args.brand;
},
addLenses : function (lenses) {
this.lenses.push (lenses);
}
});