Storing Maxobj in an Array

Dave's icon

Hi all, I'm quite new to Javascript so am learning as I go along but I can't find any reason why what I'm trying to do wont work.

I basically have a load of patches that form synthesizer modules and am writing a Javascript file which will control their creation, placement, connections and removal.
I have come as far as creating some units using 'bpatchers' and simply connecting them in the script but as there may be many instances of one patch I need to keep track of them.

What I am trying to do is create an array to store the 'Maxobj' object returned from the 'newobject' 'patcher' method. When I use a standard variable the code works fine but when I try to access properties of the 'Maxobj' stored as an array element I get the error:
• error: js: Unit Handler.js: Javascript TypeError: OSCUnit[noOSCUnits] has no properties, line 22

Here is my code so far. Note I have only implimented the array system in the "OSC Unit" case for testing purposes.

autowatch = 1;                //Recompile script on save
editfontsize = 10;                //Make the font in the text editing window 10pt

//Global Variables
//These are used to keep track of what units are present in the patcher and how they are created

    //Arrays to hold created units
var OSCUnit = new Array();

    //Variables to keep track of how many units have been created
var noOSCUnits = 0;
var noOSCFilterUnits = 0;

function create(input)
{
    switch(input)
    {
        case "OSC Unit":
            OSCUnit[noOSCUnits] = patcher.newobject("bpatcher", 300, 100, 300, 100, -220, -30, "OSC Unit.pat", 0);        //Create new OSC Unit
            OSCUnit[noOSCUnits].varname = "OSC";                                                    //Name new unit 'OSC'
            noOSCUnits ++;                                                                    //Incriment the 'noOSCUnits' variable
            OSCUnit[noOSCUnits].varname = OSCUnit[noOSCUnits].varname + noOSCUnits;                            //Concatenate the name and the number of units
            break;
        case "OSC Filter Unit":
            OSCFilterUnit = patcher.newobject("bpatcher", 300, 200, 300, 200, -190, -50, "OSC Filter.pat", 0);            //Create ne OSC Filter Unit
            OSCFilterUnit.varname = "OSCFilter";                                                        //Name new unit 'OSCFilter'
            noOSCFilterUnits ++;                                                                //Incriment the 'noOSCFilterUnits' variable
            OSCFilterUnit.varname = OSCFilterUnit.varname + noOSCFilterUnits;                                    //Concatenate the name and the number of units
            patcher.hiddenconnect(OSCUnit, 0, OSCFilterUnit, 0);
            break;
        default:
            post("No unit selected");
            break;
    }
}

Hope someone can help me solve this problem as it's the basis of degree dissertation.

Cheers, Dave.

johnpitcairn's icon

Quote: Dave wrote on Wed, 26 March 2008 09:40
----------------------------------------------------
>OSCUnit[noOSCUnits].varname = "OSC";                
noOSCUnits ++;                            
OSCUnit[noOSCUnits].varname = OSCUnit[noOSCUnits].varname + noOSCUnits;

You're incrementing noOSCUnits then attempting to use that as an array index, when that array element doesn't exist. The third line above is trying to use OSCUnit[1] when there is only 1 item in the array, OSCUnit[0].

But you should also be testing that you're actually getting an OSCUnit object created, and that manually-incremented noOSCUnits counter seems a little prone to trouble too, when OSCUnit.length or OSCUnit.push (to add an item) gives you the array size directly. So, assuming you want OSCUnit[0] to be named "OSC1":

if(obj = patcher.newobject("bpatcher", 300, 100, 300, 100, -220, -30, "OSC Unit.pat", 0)) {
noOSCUnits = OSCUnit.push(obj); // 1
obj.varname = "OSC" + noOSCUnits; // "OSC1"
// note obj and OSCUnit[0] still refer to the same object
}
else {
post("error: no OSCUnit returned");
}

Dave's icon

Thanks for your reply it helped a lot. I knew the array index would mess me up (its been over a year since I have done any programming and that was in C).

I have decided to use the array index as the OSC name suffix to make things simpler.

Here is the code I am using at the moment.

case "OSC Unit":
    if(newObj = patcher.newobject("bpatcher", 300, 100, 300, 100, -220, -30, "OSC Unit.pat", 0))
    {
        noOSCUnits = OSCUnit.push(newObj);
        OSCUnit[noOSCUnits-1].varname = "OSC" + (noOSCUnits-1);        post("nThe total number of OSC Units is: ",noOSCUnits);
        post("nThe most recent OSC Unit is: ",OSCUnit[noOSCUnits-1].varname);
    }
    else
    {
        post("No OSC Unit returned");
    }
    break;

Cheers.