1
votes

I'm trying to use a Polymer paper-dialog to display a message in response to an external event and am having difficulty even with a simple case. I'm getting an error saying 'this.$: undefined' (see code below).

<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/paper-dialog/paper-dialog.html">

<dom-module id="dialogtest-main">
    <template>
        <paper-dialog id='goodbyeDialog' modal>
            <p> Goodbye! </p>
            <div class='buttons'>
                <paper-button dialog-dismiss>Cancel</paper-button>
            </div>
        </paper-dialog>

        <p align="center">Hello...</p>
    </template>
    <script>
    doTimer = function() {
        element.openDialog();
    }

    element = {
        is: "dialogtest-main",
        ready: function() {
            window.setTimeout(doTimer, 1000);
            console.log("ready");
        },
        openDialog: function() {
            console.log("opening dialog");
            this.$.goodbyeDialog.open();
        }
    };
    Polymer(element);
    </script>
</dom-module>

I have made a few desperate stabs by placing a breakpoint in the openDialog function and executing in the console:

this.$

undefined

this.$.goodbyeDialog

TypeError: this.$ is undefined

element.$.goodbyeDialog

TypeError: element.$ is undefined

document.getElementById("goodbyeDialog")

< paper-dialog modal="" id="goodbyeDialog" class="style-scope dialogtest-main x-scope paper-dialog-0" role="dialog" tabindex="-1" aria-hidden="true" aria-modal="true" style="outline: medium none; display: none;">

document.getElementById("goodbyeDialog").open()

undefined

document.getElementById("goodbyeDialog").toggle()

undefined

Any ideas? I'm sure I must be doing something very simple wrong!

1
Why do you want to use window.setTimeout, why not directly call this.openDialog() from either ready event or attached ?SG_
I would like advise you to study JavaScript scoping and read the Polymer documentation especially the life cycle part. Otherwise you'll get this kind of issues frequently.Mason
@Mason, will do - more reading is definitely needed to avoid this in the future. Thanks for the tip.philr

1 Answers

2
votes

You have to pass this context to the methods doTimer and element.openDialog for this paper-dialog to work in this scenario. Here is the working example

I would suggest you to directly use this.openDialog() from ready or attached event of the element instead of window.setTimeout.

Polymer way of open the paper-dialog after a timeout would be using async which will run the callback function bound to this. You can replace window.setTimeout(doTimer.bind(this), 1000); with this.async(this.openDialog, 1000);

<!DOCTYPE html>
<html>  
<head>

  <title>Paperdialog-test</title>
  
  <script src="https://rawgit.com/webcomponents/webcomponentsjs/master/webcomponents.js"></script>
  
  <base href="https://cdn.rawgit.com/download/polymer-cdn/1.0.1/lib/">
  
   <link rel="import" href="paper-dialog/paper-dialog.html">
   
</head>
<body class="fullbleed">
  <dialogtest-main></dialogtest-main>

<dom-module id="dialogtest-main">
    <template>
        <paper-dialog id='goodbyeDialog' modal>
            <p> Goodbye! </p>
            <div class='buttons'>
                <paper-button dialog-dismiss>Cancel</paper-button>
            </div>
        </paper-dialog>

        <p align="center">Hello...</p>
    </template>
    <script>
    doTimer = function() {
        element.openDialog.call(this);
    }

    element = {
        is: "dialogtest-main",
        ready: function() {
            window.setTimeout(doTimer.bind(this), 1000);
            console.log("ready");
        },
        openDialog: function() {
            console.log("opening dialog");
            this.$.goodbyeDialog.open();
        }
    };
    Polymer(element);
    </script>
</dom-module>
</body>
</html>