2

I have a m("p.help") element which is removed with a click event.

I also want the element to be removed automatically after a few seconds if not clicked. I need to set a time out on it. Setting time out does not work.

function help() {
  var text = `This is a service template. Use Service section to set the schedule`;

  var node = m("p.help", {
    onclick() {
      this.parentNode.removeChild(this);
    },
  }, text);

  setTimeout(() => {
    if (node.parentNode) {
      node.parentNode.removeChild(node);
      console.log("removed");
      m.redraw();
    }
  }, 5000);

  return node;
}

The click event works fine but the time out does not work. It is not even triggered judging by the console.log()

What am I doing wrong?

EDIT

Thanks ciscoheat for the tip.

I had to put the timer in the controller for this to work.

So this one works fine:

function controller(init) {
  this.display = {
    help: true
  };
  setTimeout(() => {
    this.display.help = false;
    m.redraw();
  }, 5000);
}

function view(vm) {
  return m(".container", [
    (() => {
      var text = "Some text";
      if (vm.display.help) {
        return m("p.memo", {
          onclick() {
            this.parentNode.removeChild(this);
          }
        }, text);
      }
    })(),
  ]);
}
r.sendecky
  • 9,933
  • 9
  • 34
  • 62

1 Answers1

0

To use Mithril correctly, you should avoid DOM manipulation, leaving that to Mithril's fast diff algorithm.

Use a state variable instead, related to displaying the help paragraph that will be changed automatically after 5 seconds.

Here's a jsbin showing what I mean: http://jsbin.com/kixece/edit?html,js,output

ciscoheat
  • 3,719
  • 1
  • 35
  • 52
  • Thank you for the tip. It is a shame I did not figure this one out as I did precisely that in some other parts of the application. The only difference was I toggled the elements instead.The time out got me confused somehow. For some weird reason I assumed it should be in the view. – r.sendecky Oct 30 '15 at 01:22