MagicMirror² v2.14.0 is available! For more information about this release, check out this topic.

.resume() is executed whenever even with wrong lockString?

  • Module Developer

    Since a few years ago, the first module I created for MM, still many things I can’t understand until now. 🙂

    Recently, I found some weird thing about .resume() (and .suspend() also)

    As everyone knows, .resume() will be called when .show() is called outside. But let’s think deeper.
    Until now I thought .resume() will be called only when valid .show() is called.

    For example, if already a module is revealed, the unnecessary additional .show() will not invoke .resume(). But really does.
    And even .show() with wrong lockString, so when MM cannot reveal module, however .resume() is executed regardlessly.

    Is this the right behavior? I’m not sure this is bug or not.

    Inside of .resume(), the module cannot know this module will be shown or not. Because, to empty lockString would happen after this calling .resume().

    resume: function() {
      console.log(this.lockStrings, this.hidden) // will still have at least one lockStrings, and still this.hidden will be true.

    Let’s assume I need a time measurement of module displaying. But above code is useless, because whenever any module tries .show(), regardless its success or not, the myTimer.resume() will be executed. That is not I want.

    So, How can I solve this? Have you guys any good idea?

  • @Sean I am not near my system at the moment, but I would examine the core mm code in js/module.js and js/main,js the actual worker)

  • @Sean said in .resume() is executed whenever even with wrong lockString?:


    i always keep my own state flag… once hidden (1st time) I don’t do what hide says… same for show…

    main.js/showmodule does this

    // remove lockString if set in options.
    		if (options.lockString) {
    			var index = module.lockStrings.indexOf(options.lockString);
    			if ( index !== -1) {
    				module.lockStrings.splice(index, 1);
    		// Check if there are no more lockstrings set, or the force option is set.
    		// Otherwise cancel show action.
    		if (module.lockStrings.length !== 0 && options.force !== true) {
    			Log.log("Will not show " + + ". LockStrings active: " + module.lockStrings.join(","));
    		module.hidden = false;
    		// If forced show, clean current lockstrings.
    		if (module.lockStrings.length !== 0 && options.force === true) {
    			Log.log("Force show of module: " +;
    			module.lockStrings = [];

    it does not check if shown already… only if lockstrings exist does it reject show

  • Module Developer

    Here is my test.


    Module.register("test1", {
      start: function(){
        this.showing = true
      suspend: function () {
        console.log("@stop", this.lockStrings, this.hidden)
        this.showing = false
      resume: function() {
        console.log("@resume", this.lockStrings, this.hidden)
        this.showing = true


    Module.register("test2", {
      notificationReceived: function(noti, payload, sender) {
        if (noti == "DOM_OBJECTS_CREATED") {
      test: function() {
        const asleep = async (ms) => {
          return new Promise(resolve => setTimeout(resolve, ms))
        var target = null
          if ( == "test1") target = m
        const scenario = async () => {
          await asleep(1000)
          console.log("1. Try to show when target is revealed already")

          await asleep(1000)
          console.log("2. Try to hide with lockString 'abcd'")
          target.hide(0, {lockString:'abcd'})
          await asleep(1000)
          console.log("3. Try to show with wrong lockString '1234'")
, {lockString:'1234'})
          await asleep(1000)
          console.log("4. Try to show with right lockString 'abcd'")
, {lockString:'abcd'})
          await asleep(1000)
          console.log("5. Try to hide twice (lockString 'a', 'b')")
          target.hide(0, {lockString:'a'})
          await asleep(500)
          target.hide(0, {lockString:'b'})
          await asleep(1000)
          console.log("6. Try to unlock once. module will not be shown.")
, {lockString:'b'})
          await asleep(1000)
          console.log("7. Try to unlock once more. now module will be shown.")
, {lockString:'a'})

    The result is;

    As you see, .resume() is always called. (@ resume , current lockStrings, current hidden would be logged when it is called)
    test2 called 5 times, and test1.resume() would be executed 5 times regardless of context.

    So, What can I do with this .resume()? It is useless except counting how many times .show() is called.
    It might not be a bug, but probably out-of-sense.

  • @Sean in module1, what is this.hidden?

  • Module Developer

  • @Sean thanks. Forgot these attributes

  • @Sean I reported the bug in your issue

    	show: function (speed, callback, options) {
    		if (typeof callback === "object") {
    			options = callback;
    			callback = function () { };
    		callback = callback || function () { };
    		options = options || {};
    		this.resume();   // < --- should not be done, MM.showModule will call back if allowed
    		MM.showModule(this, speed, callback, options);

  • @Sean i see they have developed and accepted a fix for this. for next release

  • Module Developer

    Yes. I fix it with @eouia

Log in to reply