Value-Array cannot be pushed

  • I'm using Value Array to store simple data. The problem is that the array could not be access in Krpano code, but cpuld be change in js (in both console and JS action). Mixing between those doesn't look neat at all. Here are some example:

    Code
    <action name="init_action" autorun="preinit">
    	def(some_array, array);
    </action>
    <action name="sample_action" scope="local">
    	some_array.push('test');
    </action>


    When I call the action "sample_action", the console popped out this error:

    Code
    Uncaught TypeError: "length" is read-only


    Is this a bug or I'm doing something wrong?
    Thanks

  • Hi,

    the 'value arrays' in krpano ARE just Javascript Arrays, but the way krpano calls Javascript functions doesn't work for the Array push function (that's a Javascript special case).

    When doing this in krpano action code:

    Code
    some_array.push('test');


    the resulting JS code will be:

    Code
    (some_array.push).apply(some_array, 'test')


    and that 'apply' doesn't work for the Array push/pop functions (because of the way how they internally work).

    As alternative you could either extend krpano with some custom push/pop functions for value arrays or directly use Javascript Actions.

    Best regards,
    Klaus

  • Thanks for the explain! *thumbsup* I think I just need to make a work-around code like this:


    Code
    <!--Push data to value array
    args:
    args[1]: name of the array
    args[2]: value
    -->
    <action name="value_array_push" type="Javascript">
    <![CDATA[
    krpano.get(args[1]).push(args[2])
    ]]>
    </action>


    or call the push directly from jscall().
    Btw it would be nice to add some special function which could not be called to the official document.

  • Hi,

    nice workaround *wink*

    Here the same slightly optimized (predefined as Javascript function):

    Code
    <action autorun="preinit" type="Javascript">
      actions.value_array_push = function(array, val)
      {
        resolve(array).push(val);
      }
    </action>

    Or here another possibility - a custom function that 'extends' an Array object with a push function that works:

    Code
    <action autorun="preinit" type="Javascript">
      actions.add_push_support = function(array)
      {
        array = resolve(array);
        array._push = array.push;
        array.push = function(v){ array._push(v); };
      }
    </action>

    To use it:

    Code
    def(some_array, array);
    add_push_support (some_array);
    some_array.push('test');
    some_array.push('test2');
    ...
    set(debugmode,true);
    debugvar(test);
    showlog();


    Zitat

    Btw it would be nice to add some special function which could not be called to the official document.


    Do you mean Javascript functions?
    There are no general limitations, but the Array.push function is a special case in Javascript, please search for 'array push apply' to find more detailed explanations about that.

    Best regards,
    Klaus

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!