At the moment I have this in my template:
WAY 1
<template is="dom-if" if="{{_showCancel(userData.generic.id,info.userId,info._children.gigId.userId,info.accepted,info.cancelled,info.paymentTerms)}}">
And then this in my element:
_showCancel: function(viewerUserId,offerUserId,gigUserId, accepted, cancel, paymentTerms) {
// Offer needs to be accepted and NOT cancelled
if (!info.accepted || info.cancelled) return false;
// Gig owner can ALWAYS cancel an offer
if (viewerUserId == gigUserId ) return true;
// Offer maker can only cancel if the gig involved pre-payment
if (viewerUserId == offerUserId && paymentTerms != 'on-day') return true;
return false;
},
Do I have just too many parameters to this function?
Should I just have something like this instead:
<template is="dom-if" if="{{_showCancel(userData, info)}}">
Although I would want to check if their sub-properties change too... so I would need:
<template is="dom-if" if="{{_showCancel(userData, info, userData.*, info.*)}}">
But then again I probably should just look for the properties and use the value
property like so:
<template is="dom-if" if="{{_showCancel(userData.*, info.*)}}">
And then the function would be:
_showCancel: function(userDataObs, infoObs) {
var userData = userDataObs.value;
var info = infoObs.value;
if( !userData || !info) return;
...
Questions:
What would I do in cases where I have:
<paper-button
raised
hidden$="{{!_showCancel(item.id,userData.config.usersCategories,userData.config.userCategories,userData.config.usersCategories.*)}}"
>
Cancel
</paper-button>
(NOTE: usersCategories
is an Array
)
And _showCancel
being:
_showCancel: function(categoryId, userCategories) {
for (var k in usersCategories) {
var $ucat = usersCategories[k];
if ($ucat.categoryId == categoryId) {
if ($ucat.status == 'applied' || $ucat.status == 'granted') return true;
}
}
return false;
},
The point being: I want both easy access to usersCategories
, but don't want to get the value out of the "strange" array modifiers etc. So, is this a good pattern?
The "Way 1" is the right one. But, you should only reference the variables that you need, and you should always use them as they are defined in your function header.
For example, you use:
{{_showCancel(userData.generic.id,info.userId,info._children.gigId.userId,info.accepted,info.cancelled,info.paymentTerms)}}
with the following function header:
_showCancel: function(viewerUserId,offerUserId,gigUserId, accepted, cancel, paymentTerms)
.
But then inside the function, you reference info.accepted
and info.cancelled
, whereas you should used accepted
and cancelled
.
This is because inside the function, the referenced values will always be up-to-date, whereas referencing variables via this.<variable-name>
can sometimes contain older values.
In order for my answer to be complete, I will also explain certain "problems" with other ways.
Way 2: Here, you only reference the Object as a whole. This won't trigger the call via subproperty change, so it won't work as desired.
Way 3 and Way 4 are similar, and both are overkills. With the object.*
notation, you listen to all subproperty changes, which you most likely don't want.
Go with "Way 1" and make things simpler by using computed properties.
To do this, change:
<template is="dom-if" if="{{_showCancel(userData.generic.id,info.userId,info._children.gigId.userId,info.accepted,info.cancelled,info.paymentTerms)}}">
To:
<template is="dom-if" if="{{isCanceled}}">
And add the following computed property to the Polymer element:
isCanceled: {
type: Boolean,
computed: '_showCancel(userData.generic.id,info.userId,info._children.gigId.userId,info.accepted,info.cancelled,info.paymentTerms)'
}
You already have _showCancel
defined, so this is actually it. The code should work the same as your "Way 1" example, only the dom-if
is cleaner. This is especially useful if you re-use the condition on multiple occurences.
If you have any questions, don't hesitate do add a comment about it.