Polymer property observer does not trigger when keys have periods? - polymer

My Polymer module has a property that is an object called pokemonToType that maps a pokemon (string) to its type (string):
The module's ready function asynchronously adds values to the mapping.
Polymer({
is: "pokedex",
properties: {
pokemonToType: {
type: Object,
value: {},
},
},
ready() {
setTimeout(() => {
this.set('pokemonToType.bulbasaur', 'grass');
this.set('pokemonToType.charmander', 'fire');
this.set('pokemonToType.mr.mime', 'psychic');
}, 4242);
},
observers: [
"pokemonToTypeChanged(pokemonToType.*)",
],
pokemonToTypeChanged(changeRecord) {
console.log(changeRecord);
},
});
Unfortunately, this.set('pokemonToType.mr.mime', 'psychic'); fails to trigger the observer, mostly likely because the key contains a period. How could we solve this issue (trigger the observer) without removing the period from the key string (of mr.mime)?

Related

React map object and embedded object from JSON and convert to single array for state

I have a React component which is performing an axios.get call on JSON file on componentDidMount. The JSON has an object with an embedded object, like so:
This is the initial format:
"objects": {
"5bd4a1a4-f806-4355-bf34-1b4054c2881e": {
"type": "tosca.resourceTypes.TPE",
"label": "BVI 610",
"value": "801070217_BVI610"
},
and this is the console.log after my initial axios.get call.
5bd4a1a0-fd74-4a9f-b7e2-c5ab15360839: {type: "tosca.resourceTypes.TPE", label:
"Bundle-Ether 33", value: "801070217_Bundle-Ether33"}
So I could succesfully get a list of the first item using:
const finalTree = Object.keys(fullTree).map(({item}) => ({id: fullTree[item]}));
but what I need to do is convert finalTree into an array which also contains the type, label and value for each item and then put that into state. I have been messing with jsonQuery but it's not working for me and I'm a relative noobie when it comes to manipulating JSON data. Thanks in advance for any help!
You can use Object.keys to get an array of all the keys, and map that array and create a new object for each key that contains all the fields in its object and the key.
Example
const obj = {
"5bd4a1a4-f806-4355-bf34-1b4054c2881e": {
"type": "tosca.resourceTypes.TPE",
"label": "BVI 610",
"value": "801070217_BVI610"
}
};
const result = Object.keys(obj).map(key => ({
...obj[key],
id: key
}));
console.log(result);
const obj = {
"5bd4a1a4-f806-4355-bf34-1b4054c2881e": {
"type": "tosca.resourceTypes.TPE",
"label": "BVI 610",
"value": "801070217_BVI610"
}
};
const result = Object.keys(obj).map(key => ({
...obj[key],
id: key
}));
console.log(result);

How do I bind Polymer property in setTimeout?

I have a Polymer property defined as:
properties: {
delay: {
type: Timeranges,
value: '5000'
}
}
And I use this property as a timeout like this:
setTimeout(function() {
request = ajax(request, custParams, inputValue.trim(), input, result, component.subType, component.queryParams);
}, "{{delay}}");
But this is not working. If I specify a literal number as a function argument instead of "{{delay}}", it works fine. How do I bind delay here?
The property type should be Number (not Timeranges).
Polymer's data binding syntax can only be used in HTML (not JavaScript). Your current code passes a literal string to setTimeout() instead of the numeric value of delay.
Assuming setTimeout() is called from your Polymer object definition, you would use this.delay like this:
Polymer({
properties: {
delay: {
type: Number,
value: 5000
}
},
foo: function() {
setTimeout(function() {...}, this.delay);
}
});
If you need setTimeout() to be called whenever delay changes, you would use an observer like this:
Polymer({
properties: {
delay: {
type: Number,
value: 5000,
observer: '_delayChanged'
}
},
_delayChanged: function(newDelay) {
setTimeout(function() {...}, newDelay);
}
// ...
});

How to store an array of nested objects using Sails.js with MongoDB?

I'm trying to save an nested object inside a sails.js model.
This is how it looks like:
module.exports = {
schema: true,
attributes: {
label: {
type: 'string',
required: true,
},
consumption: [{
timestamp: {
type: 'string',
required: true,
},
value: {
type: 'float',
required: true,
},
}],
}
};
To include the values inside the array I'm doing the following (inside the controller):
if(!plug.consumption)
plug.consumption = [];
plug.consumption.push({
timestamp: req.param('timestamp'), /* Format: '2016-04-14T16:18:24.972Z' */
value: req.param('value'), /* Format: '6.5' */
});
plug.save(function (err){
if(err){
res.send("Error");
return next(err);
}
});
But when the plug.save is executed, sails breaks and says Error: Unknown rule: 0
I've searched how to store arrays of objects on sails.js but didn't find anything that would work.
Can anyone help?
Thanks
You syntax used in consumption is wrong or at least not documented. Waterline supports attribute types json and array as documented but you can't define a schema for them. To define a schema you have to use a One-to-Many relationship between your model and a consumption model.

Two observers Polymer

I have Two observers and in each observer I change the value of the property of the other observer. In this case I dont want that the other observer will execute.
How Can I change that The observer will execute only in change of the property from outside?
Thanks
Your best option is to use a local variable to stop the update.
Polymer({
is: 'my-element',
properties: {
myProperty: {
type: String,
observer: '_myObserverA'
}
},
observers: [
'_myObserverB(myProperty)'
],
_myObserverA(newValue) {
if(!this._localUpdate) {
//do stuff here
} else {
this._localUpdate = false;
}
},
_myObserverB(newValue) {
this._localUpdate = true;
//do stuff here
}
})
You must use an observer like that:
Polymer({
is: 'x-custom',
properties: {
preload: Boolean,
src: String,
size: String
},
observers: [
'updateImage(preload, src, size)'
],
updateImage: function(preload, src, size) {
// ... do work using dependent values
}
});
More info in: https://www.polymer-project.org/1.0/docs/devguide/properties.html#multi-property-observers

Extjs5 model default values in ajax request

I have a problem. I created a simple model and tried to save new value by using it through ajax request. But parameters which must be empty sends default value. You can see it by link under. The code does not specifically set the correct way bacause of what the console(f12) can be seen fallen challenge. In it I pass a value through a query-string, as well as through the payload-request (not yet invented how to get rid of it, as I understand it-payload is used by default). In general, instead of an empty carId call transfers Car-1.
https://fiddle.sencha.com/#fiddle/dsj
How do I fix this behavior and do that if we do not share any meaning, it passed empty?
You can create your custom proxy class that extends Ext.data.proxy.Ajax and then override buildRequest method to check for all create actions and to assign desired value to idProperty
Ext.define('CarProxy', {
extend: 'Ext.data.proxy.Ajax',
alias: 'proxy.carproxy',
type: 'ajax',
idParam: 'carId',
reader: {
type: 'json',
rootProperty: 'data'
},
api: {
create: './createcar.json'
},
writer: {
type: 'form'
},
buildRequest: function(operation) {
var request = this.callParent(arguments);
if (request.getAction() === 'create') {
request.getRecords().forEach(function(record) {
record.set('carId', ''); //assing desired value to id
});
}
return request;
}
});
Thanks everyone who answered. I want to show my solution:
add to model definition parameter
identifier: 'custom' .
And then create appropriate identifier which will return undefined on generate method:
Ext.define('Custom', {
extend: 'Ext.data.identifier.Generator',
alias: 'data.identifier.custom',
generate: function() {
return;
}
});
This is default ExtJS behaviour. If you do not specify id, it is generated. To avoid that you can for add constructor to your model:
Ext.define("Car", {
[...],
constructor: function() {
this.callParent(arguments);
// check if it is new record
if (this.phantom) {
// delete generated id
delete this.data[this.idProperty];
}
}
});