Stencil Web Components optional/required property - stenciljs

In Stencil web component there are different property annotations:
regular one:
#Prop() name;
optional:
#Prop() name?;
required:
#Prop() name!;
If there exist an explicit annotation for optional and required property, what is the requirement for regular one? If it's required - what's the purpose of using the '!' annotation in other case? If optional - what's the purpose of using the '?' annotation in other case?

According to Stencil documentation the required and optional annotations actually serve dissimilar purposes.
The "required" annotation will cause an error to be shown if the component is used without the property in other TSX.
When using the "optional" annotation, "Stencil will try to infer the type of the prop if a type is not explicitly given."
Therefore - presumably - when using no annotation, neither action will be taken.

Related

Corda Serialization Whitelist

I was trying to serialized a class (DTO) to be used in send and receive
in flows.My DTO class is not in the same module as flows. I
am getting the below errors
1.With #CordaSerializable annotation , My DTO class is not getting serialized and it is throwing
java.io.NotSerializableException: Class "class com.e_mobility.dto.dashboard.DashboardDTO" is not on the whitelist or annotated with #CordaSerializable
With manual whitelisting like below
class CustomSerializationWhiteList : SerializationWhitelist {
override val whitelist: List<Class<*>> = listOf(DTO::class.java)
}
I am getting this error during runtime
net.corda.core.serialization.internal.MissingSerializerException: Unable to create an object serializer for type class com.e_mobility.dto.dashboard.DashboardDTO:
Mandatory constructor parameters [arg0, arg1, arg2, arg3, arg4, arg5, arg6] are missing from the readable properties []
Either provide getters or readable fields for [arg0, arg1, arg2, arg3, arg4, arg5, arg6], or provide a custom serializer for this type
Please help me to resolve this error. (edited)
As you are creating a custom type, did you check that all the needed requirements are fulfilled in your class? The annotation alone might be not enough. From the related Corda documentation about serialization with custom types:
The class must be compiled with parameter names included in the .class file. This is the default in Kotlin but must be turned on in
Java using the -parameters command line option to javac
The class must be annotated with #CordaSerializable
The declared types of constructor arguments, getters, and setters must be supported, and where generics are used, the generic parameter
must be a supported type, an open wildcard (*), or a bounded wildcard
which is currently widened to an open wildcard
Any superclass must adhere to the same rules, but can be abstract
Object graph cycles are not supported, so an object cannot refer to itself, directly or indirectly

Kotlin- naming convention for boolean returning methods

What is the naming convention for boolean returning methods?
Using an 'is', 'has', 'should', 'can' in the front of method sound ok for some cases, but I'm not sure.
Is there a better way to name such methods?
for example: a function that checks card's validation. Should I call it isValidCard or cardValidation or another name?
(I didn't find it here: https://kotlinlang.org/docs/reference/coding-conventions.html)
Something about naming convention for properties in Kotlin, I know it's not for methods. But it's related:
From book Kotlin in Action (by Dmitry Jemerov & Svetlana Isakova) - section 2.2.1 Properties:
In Kotlin, properties are a first-class language feature, which entirely replaces fields and accessor methods.
Listing 2.5. Declaring a mutable property in a class:
class Person {
val name: String, // read only property: generates a field and a trivial getter
var isMarried: Boolean // writable property: a field, getter and a setter
}
Kotlin’s name property is exposed to Java as a getter method called
getName. The getter and setter naming rule has an exception: if the
property name starts with is, no additional prefix for the getter is
added and in the setter name, is is replaced with set. Thus, from
Java, you call isMarried().
For those using properties prefixed with can, should, etc. in mixed Kotlin/Java projects, you can also use #get:JvmName to make the generated Java method more idiomatic for Java clients.
For example, say you have a class like this:
class User(
#get:JvmName("canView")
val canView: Boolean
)
Without the annotation, Java clients would be forced to call user.getCanView(), but now they can call the more idiomatic user.canView().
Kotlin naming style assumes you use the Java naming conventions to the possible extend. I suggest you use this answer to the same question about Java.
UPDATE: they have released coding conventions
http://kotlinlang.org/docs/reference/coding-conventions.html

Combine JsonDeserialize#contentAs with JsonDeserialize#contentConverter or JsonDeserialize#contentUsing for custom deserialization

In JsonDeserialize annotation documentation the contentAs field is supposed to define the "Concrete type to deserialize content".
I tried to use this in combination, with either a Converter (via contentConverter field of the same annotation) or a JsonDeserializer (via contentUsing field of the same annotation), by extending either StdConverter or StdDeserializer, respectively, in an attempt to create an agnostic custom deserializer.
I cannot find a way to access the JsonDeserialize#contentAs information inside any of these two classes.
I am aware that the classes I extend from have a type parameter, I just put an Object class there. Documentation states
contentAs Concrete type to deserialize content (elements of a Collection/array, values of Maps) values as, instead of type otherwise declared. Must be a subtype of declared type; otherwise an exception may be thrown by deserializer.
Apparently I am applying the #JsonDeserializer annotation on a Collection of some persistable Class. I want to deserialize each such object, solely by knowing its id. Well, if I could only get that very type I defined in the #JsonDeserializer#contentAs field...
Can anyone tell me if this is possible anyhow?
I managed to implement the agnostic deserializer withou the use of #JsonDeserializer#contentAs after all.
After reading the javadocs of com.fasterxml.jackson.databind.JsonDeserializer I concluded that my custom deserializer should implement the com.fasterxml.jackson.databind.deser.ContextualDeserializer interface.
Inside the implementation of ContextualDeserializer#createContextual(DeserializationContext ctxt, BeanProperty property)
I could finally get access to the class type of the content of the collection, which I applied the #JsonDeserialize annotation on,
by calling:
ctxt.getContextualType().getRawClass()
NOTE that the same call inside the implementation of com.fasterxml.jackson.databind.JsonDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext) returned null, hence the need of the aforementioned interface.
All I had to do then is store the returned class in a member field (of type Class< ? >) of the custom deserializer and use it in the execution of JsonDeserializer#deserialize()
The only thing that remains to check is whether an instance of this custom deserializer is shared between threads. I only did some minor checks; I used the same implementation for two different collections of different types. I observed that ContextualDeserializer#createContextual(DeserializationContext ctxt, BeanProperty property) was called once (among multiple deserialization invokations), for each distinct type that was going to be deserialized. After checking during debugging, it seems that the same deserializer object is used for the same type. In my case, since what I store in the member field is this type itself, I don't mind if the same deserializer is used for the same java type to be deserialized because they should contain the same value. So we 're clear on this aspect as well.
EDIT: It appears all I have to do is update the com.fasterxml.jackson.databind.deser.std.StdDeserializer#_valueClass value to the now known class. Since it is final and since the ContextualDeserializer#createContextual(DeserializationContext ctxt, BeanProperty property) returns a JsonSerializer object, which is actually used,
instead of returning "this" serializer I can create a new one, passing the discovered class in the constructor, which actually sets the StdDeserializer#_valueClass to the class I actually want, and I'm all set!
Finally, NOTE that I didn't have to use the #JsonDeserializer#contentAs annotationfield as I get the value from the ctxt.getContextualType().getRawClass() statement inside ContextualDeserializer#createContextual(DeserializationContext ctxt, BeanProperty property) implementation

How to get the translation of an enumeration field?

In an entity, I have an enumeration field which is translated in english and french.
In the same entity, I have a computed field that I am using as a toString, so I would like to build the computed field with the enumeration value translated in english or french, depending on the user's locale.
My question : in the getter of my computed field written in the extension of the entity, how could I get the user's locale and translate the enumeration value ?
You have to make your extension aware of its execution context. There are several interfaces that you can implement in your extensions so that they get injected with elements of their running context.
org.jspresso.framework.model.component.IComponentFactoryAware to receive an ICompoentFactory instance
org.jspresso.framework.security.ISubjectAware to receive the instance of the logged-in Subject
org.jspresso.framework.application.backend.session.IApplicationSessionAware to receive the current instance of IApplicationSession
org.jspresso.framework.model.entity.IEntityLifecycleHandlerAware to receive an instance of IEntityLifecycleHandler
In order to fulfill your use-case, the 4th interface must be implemented. Your extension will be injected with an instance of IEntityLifecycleHandler through the following method :
void setEntityLifecycleHandler(IEntityLifecycleHandler);
Just store this instance in your extension implementation as an instance parameter and use it afterwards in your code by safely casting it as a org.jspresso.framework.application.IController.
For instance :
public String getI18nLabel() {
String translationKey = "ENUM_NAME." + getComponent().getEnumValue();
IController controller = (IController) lifecycleHandler;
return controller.getTranslation(translationKey, controller.getLocale());
}
Just remember that the pattern for the I18N resource bundle key of enumerations is ${ENUM_NAME}.${ENUM_VALUE} which is computed as the translationKey local variable in the code above.

Swap an AMD Module Dependency in Dojo

Here is a widget class declared in a MyWidget.js module.
define(["dojo/Foo","myapp/Bar"], function(Foo, Bar) { return declare('MyWidget', [], {
postCreate:function() {
var bar = new Bar();
bar.sayHello();
}
})});
In this theoretical example, "myapp/Bar" is a class defined similarly by returning a declare call. Now let's assume that I have created "myapp/SpecialBar" by extending "myapp/Bar".
In another widget, I want to tell MyWidget to use "myapp/SpecialBar" instead of "myapp/Bar" like so:
require(["myapp/MyWidget","myapp/SpecialBar"], function(Foo, SpecialBar) {
//Now swap "myapp/Bar" module dependency of "myapp/MyWidget" to "myapp/SpecialBar"
var myWidget = new MyWidget();
});
I know ways to do this. For example, I could add a Bar attribute to "myapp/MyWidget" and assign the value of the Bar module. This would allow me to instantiate like this: new MyWidget({ Bar:SpecialBar }). However, this seems like too much ceremony. Is there a clean way to just swap an AMD dependency without any special treatment to the module definition?
That is the clean way. You cannot change the modules that a widget/module depends on, well, you could map them, but that's done globally, so then it always maps to a specific module.
If you could do that, you could break a lot of stuff as well, besides, such a feature does not exist in any language. Comparing require() with imports in Java and .NET, you will see a similar trend.
The only way to change the module, is by changing the behavior/state of the module, which means by overriding properties or functions. When a module is "swappable" it's often used as a property, examples where this occur:
The dojo/dnd/Moveable class allows you to set a custom dojo/dnd/Mover through the mover property. In this case the constructor is added as a property to the Moveable (reference guide)
All widgets with a dropdown inherit from dijit/_HasDropDown, which adds the dropdown widget itself as a property to the parent widget