Related
When I run a build with stencil, I get
[Warn]
The #Prop() name "title" is a reserved public name. Please rename the "title"
prop so it does not conflict with an existing standardized prototype member.
Reusing prop names that are already defined on the element's prototype may
cause unexpected runtime errors or user-interface issues on various browsers,
so it's best to avoid them entirely.
I know it's only a warning but since it may cause unexpected runtime errors, I was wondering if some standard for naming it already existed. (since title was for me the more obvious propriety name to use).
If not, what would be the best practice?
title is a global html attribute name - 'reserved'. See https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes. As a best practice, you shouldn't use global attribute names for #Props. I don't know of any 'standard' for naming a property which is the title of your component but isn't the same as the global title attribute (which is usually used for the tooltip).
As of today, the only workaround I found was to add attributes as property and pass all the information through this variable, like the following
attributes: {
title: string
description: string
/** ... */
}
I didn't found better than that.
But I'm still open to any ideas
Properties and component attributes are strongly connected but not necessarily the same thing.
We cannot use the title variable because of the HTMLElement prop type, but we can set the field text as title like this
#Prop({ attribute: 'title' }) heading?: string;
I have come across some syntax I don't understand. The docs for data binding in Polymer explain 2 different syntaxes for data bindings:
One for binding to properties:
prop-name=...
And one for binding to attributes (e.g. href, src, style etc.):
attr-name$=...
Trying to learn from source code of existing components I have come accross the construct name\$=... and I haven't found any documentation on what that is, so far.
In the source for <paper-input> there is e.g. the following data binding for the hidden attribute on a label element:
<label hidden\$="[[!label]]" ... >[[label]]</label>
hidden is not even on the list of properties, that require attribute binding (although that list may be incomplete). So I'm feeling really stuck (and confused) here.
Why is this hidden\$=... (i.e. with a backslash) and not just hidden$=..." (without the backslash) or hidden=... (without backslash and without dollar sign)? What does this syntax do? What is it used for?
A data binding appears in the local DOM template as an HTML attribute:
property-name=annotation-or-compound-binding
attribute-name$=annotation-or-compound-binding
The left-hand side of the binding identifies the target property or attribute.
To bind to a property, use the property name in attribute form (dash-case not camelCase), as described in Property name to attribute name mapping:
<my-element my-property="{{hostProperty}}">
This example binds to the target property, myProperty on .
To bind to an attribute instead, use the attribute name followed by $:
<a href$="{{hostProperty}}">
This example binds to the anchor element's href attribute.
https://www.polymer-project.org/3.0/docs/devguide/data-binding
Although I have seen the examples in the OpenAPI spec:
type: object
additionalProperties:
$ref: '#/definitions/ComplexModel'
it isn't obvious to me why the use of additionalProperties is the correct schema for a Map/Dictionary.
It also doesn't help that the only concrete thing that the spec has to say about additionalProperties is:
The following properties are taken from the JSON Schema definition but their definitions were adjusted to the Swagger Specification. Their definition is the same as the one from JSON Schema, only where the original definition references the JSON Schema definition, the Schema Object definition is used instead.
items
allOf
properties
additionalProperties
Chen, I think your answer is correct.
Some further background that might be helpful:
In JavaScript, which was the original context for JSON, an object is like a hash map of strings to values, where some values are data, others are functions. You can think of each name-value pair as a property. But JavaScript doesn't have classes, so the property names are not predefined, and each object can have its own independent set of properties.
JSON Schema uses the properties keyword to validate name-value pairs that are known in advance; and uses additionalProperties (or patternProperties, not supported in OpenAPI 2.0) to validate properties that are not known.
For clarity:
The property names, or "keys" in the map, must be strings. They cannot be numbers, or any other value.
As you said, the property names should be unique. Unfortunately the JSON spec doesn't strictly require uniqueness, but uniqueness is recommended, and expected by most JSON implementations. More background here.
properties and additionalProperties can be used alone or in combination. When additionalProperties is used alone, without properties, the object essentially functions as a map<string, T> where T is the type described in the additionalProperties sub-schema. Maybe that helps to answer your original question.
When evaluating an object against a single schema, if a property name matches one of those specified in properties, its value only needs to be valid against the sub-schema provided for that property. The additionalProperties sub-schema, if provided, will only be used to validate properties that are not included in the properties map.
There are some limitations of additionalProperties as implemented in Swagger's core Java libraries. I've documented these limitations here.
First thing, I found a better explanation for additionalProperties:
For an object, if this is given, in addition to the properties defined in properties all other property names are allowed. Their values must each match the schema object given here. If this is not given, no other properties than those defined in properties are allowed.
So here is how I finally understood this:
Using properties, we can define a known set of properties similar to Python's namedtuple, however if we wish to have something more like Python's dict, or any other hash/map where we can't specify how many keys there are nor what they are in advance, we should use additionalProperties.
additionalProperties will match any property name (that will act as the dict's key, and the $ref or type will be the schema of the dict's value, and since there should not be more than one properties with the same name for every given object, we will get the enforcement of unique keys.
Note that unlike Python's dict that accepts any immutable value as a key, since the keys here are in essence property names, they must be strings. (Thanks Ted Epstein for that clarification). This limitation can be tracked down to pair := string : value in the json specification.
MissingMemberHandling attributes instructs Json.Net to issue an error if json text contains property that is missing from C# class. I want the inverse behaviour as well. I want that Json.Net issues an error if there is a C# property that is missing from json text.
I little bit of source digging accomplished with documentation search showed
[JsonObject(ItemRequired = Required.Always)]
Applying the above on class marks all of it fields required for de-serialization. As well, JsonObject attribute is inherited, what in my case is very helpful.
I tried to set it as a normal page-property, but no luck.
Guess I could use the DynamicProperty class but I really want to avoid this because of the no-cache issue.
Suggestions anyone?
AFAIK the only way to do this is with the DynamicProperty class. If you look at the documentation on the indexer property on the PageData object it says:
Note! Using this indexer will use the Pre and Post handlers for property lookup. I e return values are not guaranteed to belong to the page, but may be dynamic properties, "fetch-data-from"-data etc. To get data guaranteed to belong to this page, use the GetValueand SetValue methods.
Also note that setting values with this indexer will only set values that acually belong to the page, i e you may get a valid value by reading from the indexer, but trying to set a new value for the same index may yield an exception since the value does not exist in the page.
You will need to use the DynamicProperty class:
DynamicProperty myDynProp = DynamicProperty.Load(CurrentPage.PageLink, "PropertyName");
myDynProp.PropertyValue.Value = "new value";
myDynProp.Save();
Alternatively, you could circumvent the Dynamic Property using an idea Joel discusses here