Polymer: How to watch computed properties for changes - polymer

Given:
Polymer({
firstName: 'John',
lastName: 'Smith',
computed: {
name: '{{firstName}} {{lastName}}'
},
firstNameChanged: function() {
console.log('firstNameChanged')
},
lastNameChanged: function() {
console.log('lastNameChanged')
},
nameChanged: function() {
console.log('nameChanged')
},
If either the firstName or lastName is changed, then the firstNameChanged and lastNameChanged will fire, but the nameChanged never does. Does anyone know why and how I can fix it?
I'm on Polymer 0.5.x, just FYI.

Related

ng2-smart-table - How to Open Record in a Different View

I was able to add a custom action to the table but I still don't know how to use that custom action to open a record in a different page/modal when it's clicked. How to assign the ID to that record row? How to pass it to a different view?
in the component.html
<ng2-smart-table [settings]="settings" [source]="source" (custom)="onCustomAction($event)"></ng2-smart-table>
in the component.ts
settings = {
mode: 'external',
hideSubHeader: true,
actions: {
position: 'right',
add: false,
edit:false,
delete: false,
custom: [
{ name: 'viewRecord', title: '<i class="far fa-file-alt"></i>'},
],
},
columns: {
firstName: {
title: 'First Name',
type: 'string',
},
lastName: {
title: 'Last Name',
type: 'string',
},
username: {
title: 'Username',
type: 'string',
},
email: {
title: 'E-mail',
type: 'string',
},
age: {
title: 'Age',
type: 'number',
},
},
};
onCustomAction(event): void {
//WHAT TO DO HERE?
}
SOLVED
onCustomAction(event): void {
//get action name to switch in case of different actions.
var actionName = event.action;
//get row id.
var id = event.data.id;
//navigate to edit/view url.
this.router.navigate(url)
}
your can inject NbdialogService in constuctor to open in dialog/Modal
private dialogService: NbDialogService
onCustomAction(event) {
switch (event.action) {
case 'view-details':
this.service.getDetails(event.data.Id)
.pipe(
tap(res => {
this.dialogService.open(UserDetailsComponent, { // inject your component will be displayed in modal
context: {
details: res,
},
});
})
).subscribe();
break;
default:
console.log('Not Implemented Action');
break;
}
or navigate sure as you did by this.router.navigate(url)

Observer will not work in a behavior?

I found that only when I break out a observer into a behavior, no change will be detected. Are observers not able to be used in behaviors?
<iron-ajax
auto="[[activated]]"
url="[[HOST]][[LISTINGS]]/[[listingNumber]]"
handle-as="json"
verbose="true"
with-credentials="true"
on-error="_error"
loading="{{loading}}"
last-error="{{apiError}}"
last-response="{{listing}}"></iron-ajax>
</template>
<script>
Polymer({
is: 'single-listing',
behaviors: [ApiConstants, IronAjaxHelpers],
<script>
IronAjaxHelpers = {
listingNumber: {
type: Number,
value: 0,
notify: true
},
activated: {
type: Boolean,
value: false,
observer: 'setListingNumber'
},
setListingNumber: function(newValue, oldValue) {
console.log(newValue);
//this.listingNumber = id;
if (newValue === true) {
this.listingNumber = app.listingNumber;
}
}
};
</script>
Your behavior's properties should be defined inside the properties field, but it's currently at the top-level of the behavior object.
You should declare the properties inside the behavior like this:
IronAjaxHelpers = {
properties: {
/** PROPERTIES GO HERE **/
listingNumber: {
type: Number,
value: 0,
notify: true
},
activated: {
type: Boolean,
value: false,
observer: "setListingNumber"
}
},
setListingNumber: function(newValue, oldValue) {
console.log(newValue);
}
};
codepen

Why don't default nested Polymer values work?

I am using the latest 2.0-preview version of Polymer. I'd like to set default properties, and the Polymer documentation describes how to do it in Polymer 1.x. I was unable to find any changes in this approach for v2.0. But it seems to only work for primitive properties and not objects:
"use strict";
class NewElement extends Polymer.Element {
static get is() {
return 'new-element';
}
static get config() {
return {
properties: {
user: {
// type: Object, <-- doesn't help anyway
firstName: {
type: String,
value: "John",
// observer: '_callObserver' <-- FYI observers don't work properly too if this usage...
},
lastName: {
type: String,
value: "Doe"
}
},
position: {
type: String,
value: "Waiter" // <-- will set a high-level default value properly correctly
}
},
// observers: [
// '_callObserver(user.*)' <-- ...but works using this approach
// ]
}
}
constructor() {
super();
console.dir(this); // <-- see screenshots below
// this.user = { firstName: "John", lastName: "Doe" }; <-- works if initialized manually
}
}
customElements.define(NewElement.is, NewElement);
As you can see here there is a getter, and when I click on it, I see that user field is undefined.
What am I doing wrong?
It looks like you're trying to nest property declarations, which is not supported. You can declare an object property that contains subproperties (not property declarations that have type, observer, etc.).
The user property declaration:
properties: {
user: {
type: Object,
firstName: {
type: String,
value: "John",
},
lastName: {
type: String,
value: "Doe"
}
},
},
should actually look like this:
properties: {
user: {
type: Object,
value: function() {
return {
firstName: "John",
lastName: "Doe"
};
}
},
},
codepen

Polymer iron-jsonp-library component's on-data event not getting called

I am using polymer 1.0's iron-jsonp-library component to fire a cross domain call to get data. My below component's code fires the jsonp request successfully and i get the expected json data in the response. But the event specified in the "on-data" attribute of iron-jsonp-library doesn't fire. There are no javascript errors prompted in the console. Hence could not figure out what is wrong. The on-data attribute works successfully in the sample application posted by angular team member at https://github.com/surma/polymer-reddit-api. But for my cross domain call the iron-jsonp-lib component is not working as expected.
Am i doing anything wrong?
<link rel="import" href="bower_components/iron-jsonp-library/iron-jsonp-library.html">
<dom-module id="galpicker-api">
<template>
<iron-jsonp-library on-data="_loadNewData" library-url="[[_requestUrl]]" callbackName="_ajaxLoad"></iron-jsonp-library>
</template>
<script>
Polymer({
is: 'galpicker-api',
properties: {
searchtext: {
type: String,
reflectToAttribute: true,
notify: true
},
employees: {
type: Array,
readOnly: true,
value: function() {
return [];
},
notify: true
},
baseUrl: {
type: String,
reflectToAttribute: true,
value: 'https://example.com'
},
_requestUrl: {
type: String,
readOnly: true,
computed: '_computeUrl(baseUrl, searchtext)',
notify: true
}
},
_computeUrl: function(baseUrl, searchtext) {
return baseUrl + '/api/v1/Employees/search?q=' + searchtext + '&jsonp=%%callback%%';
},
_loadNewData: function(ev) {
alert(ev);
this._setEmployees(
ev.detail[0].map(function(employee) {
return {
firstName: employee.firstName,
lastName: employee.lastName,
department: employee.department
};
}));
},
_data: function(ev) {
alert(ev);
},
_ajaxLoad: function(data){
alert(data);
}
});
</script>
</dom-module>
One error is found: callbackName="_ajaxLoad" should be written callback-name=(...). If it is still usefull...

Derived attribute absent in JSON response in Sails.js

I'm writing an API for users in an example app. The api/models/User-file looks as follows:
module.exports = {
attributes: {
firstName: {
type: 'string',
required: true
},
lastName: {
type: 'string',
required: true
},
fullName: function () {
return this.firstName + ' ' + this.lastName;
}
}
};
However, when I find all my users, the derived attribute is nowhere to be found in the response:
[
{
"firstName": "Marlon",
"lastName": "Brando",
"createdAt": "2015-09-13T10:05:15.129Z",
"updatedAt": "2015-09-13T10:05:15.129Z",
"id": 8
},
{
"firstName": "Bjoern",
"lastName": "Gustavsson",
"createdAt": "2015-09-13T10:05:36.221Z",
"updatedAt": "2015-09-13T10:05:36.221Z",
"id": 10
},
{
"firstName": "Charlie",
"lastName": "Sheen",
"createdAt": "2015-09-13T10:06:59.999Z",
"updatedAt": "2015-09-13T10:06:59.999Z",
"id": 11
}
]
Am I missing something, or is it simply not possible to derive attributes like this?
When you are set attributes in Model with function it doesn't mean that it will be executed in resulting attribute. It means that you can call this function in your code. For instance, I have exactly your User model. I can make in my code smth like this:
// api/controllers/UserController.js
module.exports = {
index: function(req, res) {
User
.create({firstName: req.param('firstName'), lastName: req.param('lastName')})
.then(function(user) {
console.log(user.fullName());
return user;
})
.then(res.ok)
.catch(res.negotiate);
}
};
If you want to make it like a dynamic attribute, then you should take a look at toJSON method in your model. You can override it and implement your own logic. I think it will looks like this in your case:
// api/models/User.js
module.exports = {
attributes: {
firstName: {
type: 'string'
},
lastName: {
type: 'string'
},
fullName: function() {
return [this.firstName, this.lastName].join(' ');
},
toJSON: function() {
var obj = this.toObject();
obj.fullName = this.fullName();
return obj;
}
}
};
I didn't check this code but think that should work. You can play around with toJSON method and see what you got. Ping me in comments if code doesn't work.