How to get console output using Polymer? - polymer

I have this part of code inside dom-module tag:
<script>
Polymer({
is: "hi-world",
properties:{
name: {
type: String,
value: "default";
},
edad: {
type: Number;
},
created: function(){
console.log("The element was created")
console.log(this)
console.log(this.$)
console.log(this.$.title);
}
}
})
</script>
But when I execute the code, nothing happens in console at Chrome, Firefox or even (sorry about this) IE. What am I doing wrong? I see some guide lines at https://www.polymer-project.org/1.0/docs/devguide/registering-elements, but it doesn't work.
Also, I tried with one line console.log, with:
created: function(){
console.log("The element was created");
}
And, again, no results in web browser console.
EDIT 1:
According to a1626, the code would be, actually the solution:
<script>
Polymer({
is: "hi-world",
properties:{
name: {
type: String,
value: "default";
},
edad: {
type: Number;
}
},
created: function(){
console.log("The element was created")
console.log(this)
console.log(this.$)
//console.log(this.$.title) <-- commented, it collapses with created method
}
})
</script>

You have placed created callback inside the properties object. And during created callback elements are not prepared so you won't find using this.$.id

Related

Get value from other element in Polymer 1

I have a "login-imp.html" file (polymer 1 element) that checks the login and gets username and someID.
I need to retrieve that "someID" in other polymer element that is in another html file (modal-imp.html).
login-imp.html
<dom-module id="login-imp">
<style>...</style>
<template>
<iron-ajax id="limp" url="SOMEURL" method="POST" handle-as="json"
content-type="application/json" with-credentials="true" on-response="_handleResponse" on-error="_handleError">
</iron-ajax>
<iron-a11y-keys keys="enter" on-keys-pressed="_logIn"></iron-a11y-keys>
<div class="login">
<paper-input value={{username}} label="[[lang.login_imp.user]]" name="username"></paper-input>
<paper-input value="{{password}}" label="[[lang.login_imp.password]]" name="password" type="password"></paper-input>
<span class="error-message">[[errorMessage]]</span>
<paper-button id="login-button" on-tap="_logIn" raised>[[lang.login_imp.signin]]</paper-button>
</div>
<paper-dialog id="modalSignUp" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
<modal-signup-imp id="modal-signup-view" lang="[[lang]]" config="[[config]]"></modal-signup-imp>
</paper-dialog>
</template>
<script>
Polymer({
is: 'login-imp',
properties: {
loggedIn: {
type: Boolean,
notify: true
},
profile: {
type: Object,
notify: true,
value: function () {
return {}
}
},
username: {
type: String,
notify: true,
value: ''
},
password: {
type: String,
notify: true,
value: ''
},
retailerId: {
type: String,
notify: true,
value: ''
},
config: {
type: String
},
default: {
type: Array,
notify: true
},
lang: {
type: String
},
errorMessage: String,
observers: ['_removeMessage(username, password)']
},
ready: function () {
this.addEventListener('eventFromChild', this.closeModal);
},
_logIn: function () {
Polymer.dom(this.root).querySelector("#login-button").disabled = true;
this.$.limp.body = JSON.stringify({
"username": this.username,
"password": this.password
});
this.$.limp.generateRequest();
},
_handleResponse: function (xhrResponse) {
Polymer.dom(this.root).querySelector("#login-button").disabled = false;
var message = xhrResponse.detail.response.message;
if (message == "Access granted (" + this.username + ")") {
// save profile
this.profile = xhrResponse.detail.response.user
// change status to logged in
this.loggedIn = true;
this.username = '';
this.password = '';
//THIS IS THE ID I NEED
this.retailerId = xhrResponse.detail.response.user.id_retailer;
this._removeMessage();
}
},
_handleError: function (event) {
Polymer.dom(this.root).querySelector("#login-button").disabled = false;
this.errorMessage = [
[this.lang.errors.signin]
];
this.loggedIn = false;
},
_removeMessage: function () {
this.set('errorMessage', '');
},
signup_modal: function () {
Polymer.dom(this.root).querySelector("#modal-signup-view").xhrRetailers();
var modal = Polymer.dom(this.root).querySelector("#modalSignUp");
modal.open();
},
closeModal: function () {
var modal = Polymer.dom(this.root).querySelector("#modalSignUp");
modal.close();
}
});
</script>
</dom-module>
I've tried every way to access that object from modal-imp.html as indicated in the Polymer 1 API and docs.
-The html hierarchy:
login-imp.html -> main-imp.html -> index.html
modal-imp.html -> header-imp.html -> main-imp.html -> index.html
The code inside your login-imp.html file looks fine. You defined the retailerId as a property and have set notify to true. I presume without seeing the other files that you most likely used a wrong binding.
To clarify in your example:
What you will have to do is send the retailerId up to main-imp.html
From there you bind it down to header-imp.html and further to modal-imp.html
Example:
Inside your main-imp.html
<login-imp retailer-id="{{retailerId}}"></login-imp>
Important:
You have to use {{mustaches}} brackets when binding in two ways (in your case up)
The attribute had to be written in lower case so your property name changes to retailer-id
Define retailerId inside your main-imp.html property section
Similar Problems
Maybe a similar question I have answered explaining one & two way data-binding

Pass a config-node parameter within HTML-File to another node

I created following input-node:
<script type="text/javascript">
RED.nodes.registerType('Sensor',{
category: 'input',
defaults: {
name: {type:"InputDevice", required:true},
count: {value:"", required:true, validate:RED.validators.number()},
topic: {value:"",validate: RED.validators.regex(/^(#$|(\+|[^+#]*)(\/(\+|[^+#]*))*(\/(\+|#|[^+#]*))?$)/)},
qos: {value: "1"},
broker: {type:"mqtt-broker", required:true},
},
color:"#3FADB5",
inputs:0,
outputs:1,
icon: "feed.png",
label: function() {
//var testu = RED.nodes.getNode(config.name).inputDeviceName;
//return this.name.inputDeviceName;
return this.name||this.topic||"ClientName";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
});
And following config node:
<script type="text/javascript">
RED.nodes.registerType('InputDevice',{
category: 'config',
defaults: {
inputDeviceName: {value:"",required:true},
},
label: function() {
return this.inputDeviceName;
}
});
I can not figure out, how to pass over the parameter
inputDeviceName
to my Sensor node within the HTML File. Within the JS File, i am able to get the value of inputDeviceName with:
this.name = RED.nodes.getNode(config.name).inputDeviceName;
How can I name the sensor-node, like in the example above, to appear as 'LDR' in my flow?
You can access the properties of any node for which you know the id in a HTML file with RED.nodes.node(node_id). This will return this nodes default properties.
If you, for example, need some property from a config node, you can get its id from the value of the select HTML-element associated with the config node.

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);
}
// ...
});

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

Observe changes for an object in Polymer JS

I have an element with a model object that I want to observe like so:
<polymer-element name="note-editor" attributes="noteTitle noteText noteSlug">
<template>
<input type="text" value="{{ model.title }}">
<textarea value="{{ model.text }}"></textarea>
<note-ajax-button url="/api/notes/" method="POST" model="{{model}}">Create</note-ajax-button>
</template>
<script>
Polymer('note-editor', {
attached: function() {
this.model = {
title: this.noteTitle,
text: this.noteText,
slug: this.noteSlug
}
},
});
</script>
</polymer-element>
I want to observe changes in the model but apparently it's not possible to use modelChanged callback in the element and neither in the note-ajax-button element. What is wrong? How can I do that?
I've tried observing the fields separately, but it's not clean at all. The state of the button element you see there should change depending on the model state, so I need to watch changes for the object, not the properties.
Thanks!
To observe paths in an object, you need to use an observe block:
Polymer('x-element', {
observe: {
'model.title': 'modelUpdated',
'model.text': 'modelUpdated',
'model.slug': 'modelUpdated'
},
ready: function() {
this.model = {
title: this.noteTitle,
text: this.noteText,
slug: this.noteSlug
};
},
modelUpdated: function(oldValue, newValue) {
var value = Path.get('model.title').getValueFrom(this);
// newValue == value == this.model.title
}
});
http://www.polymer-project.org/docs/polymer/polymer.html#observeblock
Or you can add an extra attribute to your model called for example 'refresh' (boolean) and each time you modify some of the internal values also modify it simply by setting refresh = !refresh, then you can observe just one attribute instead of many. This is a good case when your model include multiple nested attributes.
Polymer('x-element', {
observe: {
'model.refresh': 'modelUpdated'
},
ready: function() {
this.model = {
title: this.noteTitle,
text: this.noteText,
slug: this.noteSlug,
refresh: false
};
},
modelUpdated: function(oldValue, newValue) {
var value = Path.get('model.title').getValueFrom(this);
},
buttonClicked: function(e) {
this.model.title = 'Title';
this.model.text = 'Text';
this.model.slug = 'Slug';
this.model.refresh = !this.model.refresh;
}
});
what I do in this situation is use the * char to observe any property change in my array, here an example of my JSON object:
{
"config": {
"myProperty":"configuraiont1",
"options": [{"image": "" }, { "image": ""}]
}
};
I create a method _myFunctionChanged and I pass as parameter config.options.* then every property inside the array options is observed inside the function _myFunctionChanged
Polymer({
observers: ['_myFunctionChanged(config.options.*)']
});
You can use the same pattern with a object, instead to use an array like config.options. you can just observe config.