Oliver Jones
Oliver Jones

Reputation: 1440

Cannot call method 'split' of undefined - Called From Function

I have a JS function that is called on load that spilts some variables, this all works well, but when I call the function from another function, I get this error Cannot call method 'split' of undefined:

function loadInAttachmentsIntoSquads(){
    // eg: 5000,5000,5000,5000 > [5000][5000][5000]
    myAttachmentArray = currentAttachments.split(',');

    //eg: [5000][5000][5000] > [5][0][0][0]
    //myAttachmentForWeapon = myAttachmentArray[mySquadsIndex].split('');

    setupWeaponAttachments();
}


function setupWeaponAttachments(){

    myAttachmentForWeapon = myAttachmentArray[mySquadsIndex].split('');

    //if(mySquadsIndex == 0){
        if(myAttachmentForWeapon[1] == 1){ // if silencer is on? //first digit is always 5
            weaponAttachments.silencer = true;
        }
        else{
            weaponAttachments.silencer = false;
        }
        if(myAttachmentForWeapon[2] == 1){ // if silencer is on? //first digit is always 5
            weaponAttachments.grip = true;
        }
        else{
            weaponAttachments.grip = false;
        }
        if(myAttachmentForWeapon[3] == 1){ // if silencer is on? //first digit is always 5
            weaponAttachments.redDot = true;
        }
        else{
            weaponAttachments.redDot = false;
        }

    // -- applies visuals -- \\
    applyWeaponAttachments();
}

If I call setupWeaponAttachments() from another function, I get that error ... why?

Upvotes: 2

Views: 16746

Answers (2)

RobG
RobG

Reputation: 147363

In the following:

> function loadInAttachmentsIntoSquads(){
>     
>     myAttachmentArray = currentAttachments.split(',');
> 
>     setupWeaponAttachments(); 
> }

The identifier currentAttachments is used as if it's a global variable. If it hasn't been assigned value, or its value isn't a string, at the time that the function is called, then an error will result.

So the fix is to make sure it has a string value:

function loadInAttachmentsIntoSquads(){
    if (typeof currentAttachments != 'string') return;
    ...
}

or deal with the error some other way.

Also, where you are doing all those if..else blocks, consider:

weaponAttachments.silencer = myAttachmentForWeapon[1] == 1;
weaponAttachments.grip     = myAttachmentForWeapon[2] == 1;
weaponAttachments.redDot   = myAttachmentForWeapon[3] == 1;

It won't be any faster, but it is a lot less code to write and read.

Upvotes: 3

Luke Sneeringer
Luke Sneeringer

Reputation: 9428

You are misunderstanding/misusing the scope rules of JavaScript.

Try passing the array you're splitting explicitly and consistently, and it should solve your problem, as well as keeping the global namespace less cluttered:

First, pass the attachments in your first function explicitly:

function loadInAttachmentsIntoSquads(currentAttachments) {
    var myAttachmentArray = currentAttachments.split(',');
    setupWeaponAttachments(myAttachmentArray);
}

Note several things I'm doing above. First, I'm adding a currentAttachments argument to the function rather than just relying on a previously-declared global variable. Second, I'm declaring myAttachmentArray as a local variable by using the var keyword. Declaring variables with var declares them in local scope; failing to do so declares them in global scope. Third, I'm manually passing the array to the setupWeaponAttachments function, in which I will also receive the argument:

function setupWeaponAttachments(myAttachmentArray) {
    var myAttachmentForWeapon = myAttachmentArray[mySquadsIndex].split('');
    // [...]
}

Notice that I again properly declare the myAttachmentForWeapon variable in local scope.

If you are more careful with managing scope and properly define functions to receive the arguments they need and operate on them, you'll save yourself lots of headache in the future, and you'll get drastically fewer problems like these.

Upvotes: 0

Related Questions