-1

I'm trying to implement some idle detection code. I have it working, thanks to some other SO posts, but I want it to be part of a Polymer Element so I can just stick <idle-fire></idle-fire> anywhere in my app and pass some parameters. Here is what I have:

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

<dom-module id="idle-fire">

<script>
    Polymer({
        is: 'idle-fire',
        properties: {
            idlelimit: {
                type: Number,
                value: 10
            }
        },
        ready: function() {


        }
    });
</script>
</dom-module>

<script>
    var idleTime = 0;
    $(document).ready(function () {
        //Increment the idle time counter every minute.
        var idleInterval = setInterval(timerIncrement, 60000); // 1 minute

        //Zero the idle timer on mouse movement.
        $(this).mousemove(function (e) {
            idleTime = 0;
        });
        $(this).keypress(function (e) {
            idleTime = 0;
        });
    });
    function timerIncrement() {
        idleTime = idleTime + 1;
        console.log("tick (" + idleTime + ")");
        if (idleTime >= 2) { // in minutes
            console.log("Idle event fired!")
        }
    }
</script>

If I try to move any piece of the <script> tag to the Polymer ready function it fails to work. And with it the way it is, I can't access the idlelimit property.

Any direction appreciated.

Community
  • 1
  • 1
  • Have you tried keeping your code outside of Polymer's constructor as it is – a1626 Dec 13 '16 at 15:35
  • I should have mentioned, yes, it works, but then I don't have access to the parameters like `idlelimit`. I will update the question. –  Dec 13 '16 at 15:35
  • you can access it using `document.querySelector('idle-fire').idlelimit`. By the way your have used **capital** `V` for `value`. This will not work `v` should be lowercased. – a1626 Dec 13 '16 at 16:44

1 Answers1

1

If I try to move any piece of the <script> tag to the Polymer ready function it fails to work. And with it the way it is, I can't access the idlelimit property.

It's possible that you're not binding the context (i.e., this) properly when setting up your callbacks. If you forget to do it at all, the context for the timer callback would be the outer context (the Window object) instead of your Polymer object, where idlelimit is available.

Here's one way to set the context for the timerIncrement callback:

// in Polymer object
setupTimer: function() {
  setInterval(timerIncrement.bind(this), 1000);
}

Alternatively, you could use ES6 arrow functions to automatically bind the context for you:

// in Polymer object
setupTimer: function() {
  setInterval(() => {
    this.idleTime++; // `this` is Polymer object
  }, 1000);
}

Here's the conversion of that code to Polymer:

HTMLImports.whenReady(() => {
  Polymer({
    is: 'idle-fire',
    properties: {
      idlelimit: {
        type: Number,
        value: 10
      }
    },
    
    attached: function() {
      // Increment the idle time counter every second.
      this._idleInterval = setInterval(this._timerIncrement.bind(this), 1000);
      this._idleTime = 0;

      // Zero the idle timer on mouse movement or keypress.
      document.onmousemove = () => { this._idleTime = 0 };
      document.onkeypress =  () => { this._idleTime = 0 };
    },

    detached: function() {
      clearInterval(this._idleInterval);
    },

    _timerIncrement: function() {
      const idleTime = ++this._idleTime;
      console.log("tick (" + idleTime + ")", this.idlelimit);
      if (idleTime >= this.idlelimit) { // in seconds for this demo
        console.log("Idle event fired!");
        clearInterval(this._idleInterval);
      }
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.7.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>
<body>
  <div>See timer in DevTools console</div>
  <div>Move your mouse over this document, or press any key to restart the timer</div>
  <idle-fire></idle-fire>
</body>

codepen

FYI: You might consider using the already available <f-idlejs> element.

tony19
  • 125,647
  • 18
  • 229
  • 307