Help troubleshooting these functions

Hi there ,

So I didn't want to have to ask but I will have to ask.
I created a function that determines the Colors of some widgets by the Velocity Received from the MIDI input

globals.apcMiniLed = function apcMiniLed(inputVelocity) {
    let outputArray = [];
    if ( inputVelocity < 7 && inputVelocity >= 0 ) {
        switch(inputVelocity){
            case 0:
                outputArray = [ '#f0f0f0' , 'paused' ];
            break;
            case 1:
                outputArray = [ '#00dd00' , 'paused' ];
            break;
            case 2:
                outputArray = [ '#00dd00' , 'running' ];
                globals.resetBlink();
            break;
            case 3:
                outputArray = [ '#dd0000' , 'paused' ];
            break;
            case 4:
                outputArray = [ '#dd0000' , 'running' ];
                globals.resetBlink();
            break;
            case 5:
                outputArray = [ '#ffcc00' , 'paused' ];
            break;
            case 6:
                outputArray = [ '#ffcc00' , 'running' ];
                globals.resetBlink();
            break;
        }
    } else {
        outputArray = [ '#00dd00' , 'paused' ];
    }
    return outputArray;
}

And this function is called on the widgets CSS that at the same time have an animation , so the previosly mentioned function returns an Array.
So the CSS property of some button wigets are like this

JS {{
    locals.c = globals.apcMiniLed(OSC{/note});
}}
:host.on {
    animation: mainBlink 1s infinite #{locals.c[1]};
    @{resetCss}
    background: #{locals.c[0]};
}

It looks like is not working for some reason , although If I test the function in other widget such as

console.log(globals.apcMiniLed(OSC{/control}));

It looks like I'm not doing it correctly.

Any ideas?

Thanks

locals.c[1] is a color, right ? Css animation doesn't take colors as arguments.
Also, make sure there is a semi colon after @{resetCss} or at the end of what @{resetCss} returns, otherwise the css may break.

1 Like

No , locals.c[1] is the animation state (eiher running or paused) ,

I have changed it a bit accordingly

JS {{
    locals.c = globals.apcMiniLed(OSC{/note});
}}
:host{
    background: #{locals.c[0]};
}
:host.on {
    animation: mainBlink 1s infinite #{locals.c[1]};
    @{resetCss};

}

And looking at the console when sending some MIDI messages to the device at least I get an error message

button-01.css #{} error at line 2: TypeError: Cannot read properties of undefined (reading '0')

Although If I use the same syntax in a script Property of any widget it will work and load the functions
Such as

locals.c = globals.apcMiniLed(OSC{/note});
console.log(locals.c);

Right, my bad.

button-01.css #{} error at line 2: TypeError: Cannot read properties of undefined (reading '0')

This happens when OSC{/note} has not received its first value (and is undefined), you can give it a default value to avoid that.

The class you want to target is "active", not "on" (you can use the browser inspector to see the widget's structure and classes). (woops, that's not true :))

1 Like

I have added a default value an not even with that is working.
It looks like the global function is not been parsed properly in that CSS property of that widget (in the JS{{}} statement of it) , whereas if you are to call that same function in the "scripting" property it will be parsed properly.

What do you mean by using the browser to inspect the element? Basicallly to check the parsed CSS on the rendered element? It doesn't tell much . If only I could traverse the DOM and identify the actual JS code within the broswser that would be great to see what is going on.

virtual-apcmini-1.json (159.1 KB)

(only if you have time) , see button-01 vs fader-01 . fader-01 if you send to it Midi Messages it does parse them as the call to the function is in the "scripting" property of the widget , whereas in button-01 as it is in the CSS property it wont for some reason...

There's a space between JS and {{ that shouldn't be here, I didn't spot it before. By the way, you only need one pair of brackets in the JS{} syntax since v1.9.4.

1 Like

I have been having that issue ... thank you really. I'm now deugging other thing but it should be fine cheers!!

Ok so I reached this error message which is like the end-game credits for me lol

fader-01.css JS{} error: RangeError: Maximum call stack size exceeded
fader-01.css JS{} error: SyntaxError: Invalid regular expression: /(#W8u4TpCP71)\s*\1(?=[\s\r\n,{])/: Stack overflow
fader-01.css JS{} error: SyntaxError: Invalid regular expression: /(#W8u4TpCP71 )(\s*(?:to|from|[+-]?(?:(?:\.\d+)|(?:\d+(?:\.\d*)?))%))(?=[\s\r\n,{])/: Stack overflow

The issue is in this function that calls another function, but this function was tested previously in isolation and should be fine , I don't see any endless loop going on in here. It just takes a good time to process (which makes me think that the functionality is impossible to achieve at least by using this method)

`globals.resetBlink = function resetBlink () {
  set('resetCss', 'animation:none')
  setTimeout(()=>{
  set('resetCss', '')
  })
}


globals.apcMiniLed = function apcMiniLed(inputVelocity) {
    let outputArray = [];
    if ( inputVelocity < 7 && inputVelocity >= 0 ) {
        switch(inputVelocity){
            case 0:
                outputArray = [ '#f0f0f0' , 'paused' ];
            break;
            case 1:
                outputArray = [ '#00dd00' , 'paused' ];
            break;
            case 2:
                outputArray = [ '#00dd00' , 'running' ];
                globals.resetBlink();
            break;
            case 3:
                outputArray = [ '#dd0000' , 'paused' ];
            break;
            case 4:
                outputArray = [ '#dd0000' , 'running' ];
                globals.resetBlink();
            break;
            case 5:
                outputArray = [ '#ffcc00' , 'paused' ];
            break;
            case 6:
                outputArray = [ '#ffcc00' , 'running' ];
                globals.resetBlink();
            break;
        }
    } else {
        outputArray = [ '#00dd00' , 'paused' ];
    }
    return outputArray;``

Just throwing it out here , sharing is caring, I will look after you as well guys :smiley:

Can you upload your session again ?

virtual-apcmini-1.json (159.3 KB)

Check fader-01 is the one I'm checking it with now (just for the console.log on scripting) but the functionality is gonna be in button-01 and so on...

What should I do to reproduce the error exactly ?

So , if you send a Midi Message to the virtual-apcmini , to [144 , 56 , (some velocity) ] basically channel 1 of Note On message on The note 56 you should be triggering button-1 , and it does trigger , issue is with the 2 , 4 and 6 velocities which trigger the blinking effect (therefore the other function which creates the stackoverflow)

You can for instance send a control change note to [176 , 48, (some velocity) ] which is pointing to widget "fader-01" it will parse the messages in the console (as its scripting have a control.log , pointing to the function)

Thanks

Ok, I understant the issue. First, there is the infinite loop : globals.apcMiniLed() changes the value of @{resetCss}, which triggers the recalculation of the property where you call globals.apcMiniLed(). But more importantly, you can't call setTimeout and set from JS{} blocks, these are only meant to be called from scripts. Using the globals object to bypass this limitation leads to unpredictable behaviors (errors) and is not supported.

In next release, these unpredictable behaviors will be replaced with an explicit error message.

Now as to how to make this work... I think you should refactor and handle scripted things from the custom module to keep things simpler in the interface : filter incoming MIDI in the custom module, send colors to OSC{/addresses} that don't conflict with the original midi messages and trigger the resetCss script by sending a value to a simple script widget, etc.

1 Like