11

I was wondering if it was possible to pass a function foo() as an attribute func="foo()" and have it called this.func() inside of the polymer element?

<foo-bar func="foo()"></foo-bar>


Polymer({
  is: 'foo-bar',
  properties: {
    func: Object,
  },
  ready: function() {
    this.func();
  }
});

I've been trying to get this working for ages with no luck.

Thanks in advance.

Flying Emu
  • 430
  • 6
  • 14
  • So your parent element defines the function `foo` and your child element (`foo-bar`) is trying to call it? – Ben Thomas Jul 06 '15 at 14:21
  • @BenThomas it's just passing a function as an attribute value. We'll just assume for simplicity that appears like such in the HTML document. There is no parent element in this case. – Flying Emu Jul 07 '15 at 02:45
  • There are [more answers to this question here](https://stackoverflow.com/q/31441401/1640892). ... https://stackoverflow.com/q/31441401/1640892 – Let Me Tink About It Feb 04 '18 at 19:36

1 Answers1

3
<foo-bar func="foo()"></foo-bar>



Polymer({
  is: 'foo-bar',
  properties: {
    func: {
        type: String, // the function call is passed in as a string
        notify: true
  },
  attached: function() {
    if (this.func) {
        this.callFunc = new Function('return '+ this.func);
        this.callFunc(); // can now be called here or elsewhere in the Polymer object
  }
});

So the trick is that "foo( )" is a string when you first pass it to the Polymer element. I fought with this for a while as well and this is the only way I could find to get it done. This solution creates a function that returns your function call, which you assign as the value of one of your polymer element properties.

Some people might say you shouldn't use the Function constructor because it is similar to eval( ) and.... well you know, the whole 'eval is evil' thing. But if you're just using it to return a call to another function and you understand the scope implications then I think this could be an appropriate use-case. If I'm wrong I'm sure someone will let us know!

Here's a link to a nice SO answer about the differences between eval( ) and the Function constructor in case it can help: https://stackoverflow.com/a/4599946/2629361

Lastly, I put this in the 'attached' lifecycle event to be on the safe side because it occurs later than 'ready'. I'm not sure if an earlier lifecycle event or 'ready' could be used instead of 'attached'. Perhaps someone can improve this answer and let us know.

Community
  • 1
  • 1
CoolestUsername
  • 195
  • 2
  • 11
  • 1
    The function constructor still functions very similarly to eval() but never-the-less I'm pretty sure your suggestion it's the only way to pass a function as an attribute. I've probably going to abandon this idea because of the CSP default restrictions and what not. – Flying Emu Aug 23 '15 at 12:11