dojo/store/Observable what is the correct usage? - dojo

Below documentation shows the usage of Observable with and without the "new" keyword.
http//dojotoolkit.org/reference-guide/1.9/dojo/store/Observable.html
// create the initial Observable store
store = new Observable(new Memory({data: someData}));
http//dojotoolkit.org/documentation/tutorials/1.6/realtime_stores/
Note: despite its capital "O" and dedicated module, dojo.store.
Observable is not a constructor; it is simply a function which
takes a store, wraps it with observe functionality, then returns it.
Therefore, the new keyword should not be used with dojo.store.Observable.
http://dojotoolkit.org/documentation/tutorials/1.7/realtime_stores/
// wrap the store with Observable to make it possible to monitor:
marketStore = Observable(marketStore);
What is the correct usage?
If both are correct? when should a particular usage be preferred over the other.
Frank.

It doesn't really matter. What happens behind the screens is very similar. When you call the Observable as a function like:
var store = Observable(new Memory({ data: [] }));
Then it will use return value of the Observable() method (which is the observable store).
When you're using the new keyword, you're creating a new instance of Observable, in JavaScript that means that the Observable() function itself will be seen as the constructor of the new instance.
However, when you're providing a return value from inside the constructor, that object (when being a complex object) is used as the instance in stead. So in this case it returns the observable store, so that will be used as the instance. A good article to read what happens if something is being returned from a constructor function can be found here.
The naming of it (starting with a capital letter) makes you think it's an instance of Observable, but it isn't. The ultimate proof to that is the following:
new Observable(new Memory({ data: [] })) instanceof Observable // Returns false
The following returns false and in case of a real instance it would return true.
Summarized, both ways will return an observable store. There is no difference in it, even performance wise both are very similar.
So it doesn't really matter what you use, the only thing I can tell you is that it behaves like a normal function and not as a constructor.

Related

What is the difference between ref, toRef and toRefs

I have just started working with Vue 3 and Composition API.
I was wondering what are the differences between ref, toRef and toRefs?
Vue 3 ref
A ref is a mechanism for reactivity in Vue 3. The idea is to wrap a non-object inside a reactive object:
Takes an inner value and returns a reactive and mutable ref object. The ref object has a single property .value that points to the inner value.
Hmm.. Why?
Vue 3 relies on JavaScript proxies to detect changes to your reactive data and implement the reactivity. Proxies are essentially event listeners for objects: any reading or writing on a proxied object triggers the proxy, which can then do something with the values. This is convenient for reactivity since the variable changing will provide a trigger from which Vue can update any dependencies.
But proxies require objects to work. So Vue provides the ref method to convert your non-object variables into objects and then to grant reactive capabilities through a proxy. (Objects are reference variables, hence the name ref.)
(And Vue automatically unwraps your refs in the template, which is an added benefit of ref that you wouldn't get if you wrapped your value variables in an object manually.)
reactive
If your original variable is already an object (or array), a ref wrapping is not needed because it is already a reference type. It only needs Vue's reactive functionality (which a ref also has):
const state = reactive({
foo: 1,
bar: 2
})
But now consider copying a property from the object above to a new variable, for example foo which contains the number 1. If you copied this to a new variable, the copy would of course be a regular, non-reactive variable having no connection to the reactive object it was copied from. If foo changed later, the copy would not, meaning the copy is not reactive. This is where toRef is useful.
toRef
toRef converts a single reactive object property to a ref that maintains its connection with the parent object:
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
/*
fooRef: Ref<number>,
*/
Now if state.foo changes, fooRef.value will change as well. So toRef has enabled copying a value property in such a way that the copy also has a reactive connection to the original parent object.
toRefs
toRefs converts all of the properties, to a plain object with properties that are refs:
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
/*
{
foo: Ref<number>,
bar: Ref<number>
}
*/
When would I ever use toRef or toRefs?
The most likely time would be when importing a reactive object, say from a composable, and destructuring it. The act of destructuring will pull the current property value from the object into a new local variable that will not be reactive without toRef. You may notice this when importing and destructuring a Pinia store into your component, for example.
reactive
reactive creates a deeply reactive proxy object based on a given object. The proxy object will look exactly the same as the given, plain object, but any mutation, no matter how deep it is, will be reactive - this includes all kinds of mutations including property additions and deletions. The important thing is that reactive can only work with objects, not primitives.
For example, const state = reactive({foo: {bar: 1}}) means:
state.foo is reactive (it can be used in template, computed and watch)
state.foo.bar is reactive
state.baz, state.foo.baz, state.foo.bar.baz are also reactive even though baz does not yet exist anywhere. This might look surprising (especially when you start to dig how reactivity in vue works). By state.baz being reactive, I mean within your template/computed properties/watches, you can write state.baz literally and expect your logic to be executed again when state.baz becomes available. In fact, even if you write something like {{ state.baz ? state.baz.qux : "default value" }} in your template, it will also work. The final string displayed will reactively reflect state.baz.qux.
This can happen because reactive not only creates a single top level proxy object, it also recursively converts all the nested objects into reactive proxies, and this process continues to happen at runtime even for the sub objects created on the fly. Dependencies on properties of reactive objects are continuously discovered and tracked at runtime whenever a property access attempt is made against a reactive object. With this in mind, you can work out this expression {{ state.baz ? state.baz.qux : "default value" }} step by step:
the first time it is evaluated, the expression will read baz off state (in other words, a property access is attempted on state for property baz). Being a proxy object, state will remember that your expression depends on its property baz, even though baz does not exist yet. Reactivity off baz is provided by the state object that owns the property.
since state.baz returns undefined, the expression evaluates to "default value" without bothering looking at state.baz.qux. There is no dependency recorded on state.baz.qux in this round, but this is fine. Because you cannot mutate qux without mutating baz first.
somewhere in your code you assign a value to state.baz: state.baz = { qux: "hello" }. This mutation qualifies as a mutation to the baz property of state, hence your expression is scheduled for re-evaluation. Meanwhile, what gets assigned to state.baz is a sub proxy created on the fly for { qux: "hello" }
your expression is evaluated again, this time state.baz is not undefined so the expression progresses to state.baz.qux. "hello" is returned, and a dependency on qux property is recorded off the proxy object state.baz. This is what I mean by dependencies are discovered and recorded at runtime as they happen.
some time later you change state.baz.qux = "hi". This is a mutation to the qux property and hence your expression will be evaluated again.
With the above in mind, you should be able understand this as well: you can store state.foo in a separate variable: const foo = state.foo. Reactivity works off your variable foo just fine. foo points to the same thing that state.foo is pointing to - a reactive proxy object. The power of reactivity comes from the proxy object. By the way, const baz = state.baz wouldn't work the same, more on this later.
However, there are always edge cases to watch for:
the recursive creation of nested proxies can only happen if there is a nested object. If a given property does not exist, or it exists but it is not an object, no proxy can be created at that property. E.g. this is why reactivity does not work off the baz variable created by const baz = state.baz, nor the bar variable of const bar = state.foo.bar. To make it clear, what it means is that you can use state.baz and state.foo.bar in your template/computed/watch, but not baz or bar created above.
if you extract a nest proxy out to a variable, it is detached from its original parent. This can be made clearer with an example. The second assignment below (state.foo = {bar: 3}) does not destroy the reactivity of foo, but state.foo will be a new proxy object while the foo variable still points the to original proxy object.
const state = reactive({foo: {bar: 1}});
const foo = state.foo;
state.foo.bar = 2;
foo.bar === 2; // true, because foo and state.foo are the same
state.foo = {bar: 3};
foo.bar === 3; // false, foo.bar will still be 2
ref and toRef solve some of these edge cases.
ref
ref is pretty much the reactive that works also with primitives. We still cannot turn JS primitives into Proxy objects, so ref always wraps the provided argument X into an object of shape {value: X}. It does not matter if X is primitive or not, the "boxing" always happens. If an object is given to ref, ref internally calls reactive after the boxing so the result is also deeply reactive. The major difference in practice is that you need to keep in mind to call .value in your js code when working with ref. In your template you dont have to call .value because Vue automatically unwraps ref in template.
const count = ref(1);
const objCount = ref({count: 1});
count.value === 1; // true
objCount.value.count === 1; // true
toRef
toRef is meant to convert a property of a reactive object into a ref. You might be wondering why this is necessary since reactive object is already deeply reactive. toRef is here to handle the two edge cases mentioned for reactive. In summary, toRef can convert any property of a reactive object into a ref that is linked to its original parent. The property can be one that does not exist initially, or whose value is primitive.
In the same example where state is defined as const state = reactive({foo: {bar: 1}}):
const foo = toRef(state, 'foo') will be very similar to const foo = state.foo but with two differences:
foo is a ref so you need to do foo.value in js;
foo is linked to its parent, so reassigning state.foo = {bar: 2} will get reflected in foo.value
const baz = toRef(state, 'baz') now works.
toRefs
toRefs is a utility method used for destructing a reactive object and convert all its properties to ref:
const state = reactive({...});
return {...state}; // will not work, destruction removes reactivity
return toRefs(state); // works

What is difference between global methods and instance methods in Vue.js?

Vue.js official docs about plugins describes global methods and properties and Vue instance methods.
// 1. add global method or property
Vue.myGlobalMethod = function () {
// some logic ...
}
// 4. add an instance method
Vue.prototype.$myMethod = function (methodOptions) {
// some logic ...
}
But it isn't clear which of this approach is better fit to define global functionality? Can someone explain difference or indicate some resource about different use cases of this two approaches?
An instance method will have an instance (this) to be called from an operate on. A global-on-Vue function would have Vue itself as its this, which probably means you wouldn't want to use this in it.
So: instance method if it should operate on an instance, global function if it is some sort of utility that doesn't operate on a Vue instance.

Why Property must be initialized when there is auto back-end field generated

I'm new to properties and moved from the java to kotlin. I'm struggling with the properties, I learned much about it but initializing the properties are confusing me, when it should be initialized or when it can work without initialization.
Let me explain it by the help of code. Below is the code which is requiring to initialize the property when the back-end field generated, before posting the code let me post the paragraph from the kotlin official website.
A backing field will be generated for a property if it uses the
default implementation of at least one of the accessors, or if a
custom accessor references it through the field identifier.
Now here is the code below.
class Employee{
var data: String // because there are default implementation of get set
// so there will be a back-end field.
}
So I have to initialize it else compilation error.
Ok I can understand it as that some one can access it so there will be no value which can produce the wrong result.
Then I move next to understand it more, so I add custom getter.
class Employee{
var data: String
get() = "default value"
}
This also generate the back-end field so compilation error to initialize it. I can understand it as that there is no initialized value so compiler complain about it.
May be compiler is not smart enough yet to check that there is value which is giving result for this property by custom getter so don't complain about initializing just return that value when required.
But there should be not a problem if any one access it then a default value is already there, then why compiler still complain?
Then I move one step more to implement custom setter too.
class Employee{
var data: String
get() = "default value"
set(value){
field = value
}
}
Still there is the back-end field because we have accessed the field so compiler generate the back-end field.
Same error, should be initialized.
Then the final stage where it works fine as below.
class Employee{
var data: String
get() = "default value"
set(value){
}
}
Now I'm not accessing field in custom getter setter so there is not a back-end field. And it works fine.
So the final question when the property should be intialized? When there is a back-end field generated?
Yes this does not compile:
class Employee{
var data: String
get() = "default value"
}
but this does:
class Employee{
val data: String
get() = "default value"
}
so maybe the compiler by stating Property must be initialized for the wrong declaration, wants from you to admit that data is something that you can not change. I say maybe.
Now the part that does compile:
class Employee{
var data: String
get() = "default value"
set(value){
}
}
This is where you explicitly admit that whatever happens I will never set a value to data, and that's why the compiler feels fine.
Just to save you from more confusion, there's a lot of explaining about Kotlin in the Internet and you may find it very difficult to get familiarized with this relatively new language, but keep in mind that everything needs to be tested by you.
I found the below code in a web page:
class User{
var firstName : String
get() = field
set(value) {field = value}
var lastName : String
get() = field
set(value) {field = value}
}
and it is presented as compilable when it's not.
You kind of answered your own question. There's no backing field when you override both getter and setter, and don't access field.
About your "compiler not being smart enough": get() function is actually RAN at runtime, so writing a lot of compiler code just to evaluate if return value is static and should be injected as default is too niche of a use case.
If your getter depends on another field which is only initialized later, this would cause a lot of confusion as to what default value should be.
Consider this code, assuming value of provider is not defined:
var data: String
get() = provider.data
What would be a default value? Do you want a null? Empty string? Maybe entire object initialization should crash? Explicit default value declaration is needed for that purpose.
That's where idea of lateinit var came to be: if You're certain you will set value before performing any get, You can use this keyword to prevent compiler errors and setting default value.
class Employee{
var data: String
get() = "default value"
}
var means there are both a getter and a setter. Because you didn't write a setter, you get the default one, which accesses the backing field. So there is a backing field, and it needs to be initialized.
But there should be not a problem if any one access it then a default value is already there, then why compiler still complain?
Because that makes the rules simpler: all properties with backing fields must be initialized. This in turn may be because in Java fields don't have to be initialized and this is a known source of bugs. I would like to say it also avoids a possible bug, because presumably you don't actually want the setter's result never to be accessible, but initializing doesn't fix that problem.
I don't see any obvious problem with changing the rules so that a field only needs to be initialized when accessed in the getter, and maybe adding a warning when only one accessor uses field. But I may be missing something, and don't see much benefit to doing so either.

Recommended pattern for setting initialization parameters to custom widget

I'm creating my own template based widgets and I was trying to pass some objects through the constructor on creation like this
var widget = new myWidget(obj1, obj2, obj3);
where my constructor of the widget looks like
constructor: function(param1, param2, param3)
However I was getting some errors and found they were due to _WidgetBase functionality (specifically the create method) that is expecting something special in the first and second parameters.
create: function(params, srcNodeRef)
So in order to avoid my parameters nuking the params, and srcNodeRef that was expected in position one and two, I had to move my parameters to after the second position like this
constructor: function (params, srcNodeRef, myParam1, myparam2, myParam3)
But naturally this is not an expected way to solve this compared to the usual way to instantiate objects in normal object oriented languages (ex. c#)
My question is, is there a recommended pattern for passing initialization parameters to a custom widgets constructor, that avoids this issue of having to remember the first and second parameter positions are reserved?
NOTE:
An important note is that whatever parameters I send into the widget, must be acted on or made available before postCreate executes, just like it is if I passed them to the constructor.
Actually, there is a "dojo" way to pass parameters into your widget:
var widget = new myWidget({obj1: obj1, obj2: obj2});
In instance of your widget these object will refer to
this.obj1, this.obj2. You don't have to override constructor.
Some comments from dojo source of _WidgetBase on this topic:
//////////// INITIALIZATION METHODS ///////////////////////////////////////
/*=====
constructor: function(params, srcNodeRef){
// summary:
// Create the widget.
// params: Object|null
// Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
// and functions, typically callbacks like onClick.
// The hash can contain any of the widget's properties, excluding read-only properties.
// srcNodeRef: DOMNode|String?
// If a srcNodeRef (DOM node) is specified:
//
// - use srcNodeRef.innerHTML as my contents
// - if this is a behavioral widget then apply behavior to that srcNodeRef
// - otherwise, replace srcNodeRef with my generated DOM tree
},
=====*/
I +1'd Kirill's answer as that's the easiest. But from the other comments it sounds like you might need to massage the input or initialize other variables based on the input.
If so, take a look at the postMixinProperties lifecycle method and override it in your widget. If your widget is templated and the template expects the massaged data, you'll need this. In here you refer to your properties with this as you expect.
postMixInProperties: function(){
// summary:
// Called after the parameters to the widget have been read-in,
// but before the widget template is instantiated. Especially
// useful to set properties that are referenced in the widget
// template.
// tags:
// protected
},
Don't forget to invoke this.inherited(arguments); in here as you should in all of the dijit lifecycle methods.
Defining setters for you properties is another way to massage these properties. You'll want this if a template will use these properties. Example of a setter from the Writing Widgets page. So here 'open' would be the name of the parameter as passed to the contructor, or in a widget template.
_setOpenAttr: function(/*Boolean*/ open){
this._set("open", open);
domStyle.set(this.domNode, "display", open ? "block" : "none");
}

Using dojo.require() without dojo.declare()

I'm quite confused from Dojo's documentation. How can I use dojo.require() without actually using dojo.declare()? The reason I don't want to use dojo.declare() is that it exposes declared class as global variable.
Right now my code looks like this:
HTML file:
dojo.require('module.test');
Module/test.js:
dojo.provide('module.test');
function test() {
return 'found me';
}
I just can't get Dojo to return test() method anywhere. What's the correct pattern for using dojo.require() without declaring?
I think you are confusing dojo.provide/dojo.require with dojo.declare. They are completely different concepts.
Things that relate to modules
dojo.provide defines a module.
dojo.require requires that a module be defined before running any code later.
Things that relate to JavaScript classes
dojo.declare is something completely different. It declares a Dojo-style class.
You can have multiple classes in a module, or several modules making up one class. In general, modules !== classes and they are completely unrelated concepts.
dojo.provide defines the code module so that the loader will see it and creates an object from the global namespace by that name. From that point, you can anchor code directly to that global variable, e.g.
Module/test.js:
dojo.provide('module.test');
module.test.myFunc = function() {
return 'found me';
}
There are various patterns you can use, such as creating a closure and hiding "private" function implementations, exposing them via the global reference you created in dojo.provide:
dojo.provide('module.test');
function(){
// closure to keep top-level definitions out of the global scope
var myString = 'found me';
function privateHelper() {
return myString;
}
module.test.myFunc = function() {
return privateHelper();
}
}();
Note that the above simply puts methods directly on an object. Now, there's also dojo.declare, which is often used with dojo.provide to create an object with prototypes and mixins so that you can create instances with the 'new' keyword with some inheritance, even simulating multiple inheritance vai mixins. This sort of OO abstraction is often overused. It does approximate the patterns required by languages like Java, so some folks are used to declaring objects for everything.
Note that as of Dojo 1.5, dojo.declare returns an object and does not necessarily need to declare anything in the global scope.
Here's a pattern I sometimes use (this would be the contents of test.js):
(function() {
var thisModule = dojo.provide("module.test");
dojo.mixin(thisModule, {
test: function() {
return "found me";
}
});
})();
Now you can reference module.test.test() in your HTML page.