patcher.getnamed not finding named objects

Anthony Palomba's icon

I have a max send object in my patch that I have named "test_send".
In my js script, I make the following call...

function loadbang()
{
    obj = patcher.getnamed("test_send");
}

obj ends up being null! Can someone please explain why this
is not working?

Thanks,
Anthony

pdelges's icon

As you call getnamed at loadbang, maybe it's called before the object has been named... I had similar problems with named objects and JavaScript and had to use a deferlow (so no loadbang function in the JS).

I read in the doc (https://cycling74.com/docs/max6/dynamic/c74_docs.html#jsbasic -> Global Code) that you cannot Refer to your object’s Patcher (see the Patcher Object for more information) in the Global Code.

p

amounra's icon

What you describe happens to me, too. I usually try to set everything up after I'm sure the patch has loaded completely.

If you're just trying to send something through the object, you can just use '.messnamed()' to address the send. Otherwise, you could either initialize your local assignments from outside the patch, or try using a Task() object and use its .schedule() method in loadbang() to call a seperate function that makes your scripting assignments:

var obj;
var getstuff = new Task(this, getstuffnow);
function loadbang(){
  getstuff.schedule(1000);
}
function getstuffnow(){
  obj = this.patcher.getnamed("test_send");
}

Tasks have been flaky on me in the past, but I've found them to be much more reliable in Max6.

edit::I just noticed after rereading Patrick's post that you're using the variable "patcher" to refer to the patcher without the jsthis instance. If you've defined "patcher=this.patcher" in global code, that might be why its not working. It should be:

this.patcher.getnamed('whatever')

Anthony Palomba's icon

Hey guys, thanks for your replies. But I am still seeing some odd behavior...

So I moved my js object init code to a function that I manually trigger
once the patcher is already loaded.

    dsend = patcher.getnamed("test_send");

This line still returns null. Just so that I am clear on this,
getnamed should return the object whose script name matches
"test_send". Yes? Am I missing something?

Anthony

amounra's icon

Again, the syntax should be:

dsend = this.patcher.getnamed("test_send");

Anthony Palomba's icon

I tried both, no difference.

this.patcher.getnamed and patcher.getnamed should resolve to the
same thing. Unless I have defined a variable called "patcher" of my own.

Ben Bracken's icon

Anthony,

Does your send object have the varname set to 'test_send'? The send 'name' that you set in the box as an argument is different than a varname.

-Ben

amounra's icon

Oh, right. Of course it should :) I should have thought about that a moment longer.

Anthony Palomba's icon

Ben, I am setting the scripting name of the object. I am not sure if this is the same
thing as the varname. The send name and scripting name are different.

But I think I have found the problem. It appears that if my js object is in a subpatcher,
and the send object is in the root patcher, this.patcher.getnamed does not find the object.

It seems like patcher.getnamed does not have a global scope. Is this correct?

Luke Hall's icon

Getnamed can only see where you point it which, in your example, is in this.patcher. If you want it to look into a subpatcher or parent patcher you have to tell it explicitly where to go!

Anthony Palomba's icon

Is there a way I can tell it to start at the root patcher?

Anthony Palomba's icon

Okay I have come up with something that works. The following function
will find a named object globally. Which is the way I think getnamed should
be implemented in the first place.

function FindObj(objname)
{
    var root = this.patcher;
    while(root.parentpatcher != null)
        root = root.parentpatcher;

    var obj = root.firstobject;
    while(obj != null)
    {
        if(obj.varname == objname)
            return obj;

        nextobj = obj.nextobject;
        if(obj == nextobj )
            break;
        else
            obj = nextobj ;
    }
    return null;
}

julynessi's icon

write custom init function and trigger by another loadbang + deferlow object

Anthony Palomba's icon

Again, the scope of getnamed() is the patcher. How does your suggestion solve this problem?