0

I am fairly new to javascript and jquery. I thought i had learned enough to do this, but apparently not. I think the code is fairly self explanatory.

The problem is that ArrowDir is apparently undefined. It looks defined to me, but I'm sure I'm missing something obvious.

function ArrowDir(){
    var up = function(){
        $("#arrow").attr('src','up_arrow.jpg');
    };

    var down = function(){
        $("#arrow").attr('src','down_arrow.jpg');
    };
}

$(function () {
    if($("#toggle").onclick){
        ArrowDir().down();
    };
});

I've tried assigning the function as a variable, var ArrowDir = function(), but it doesn't seem to make a difference

ForceMagic
  • 6,230
  • 12
  • 66
  • 88
  • I've updated the indentation and formatting to match the original post, and left the missing quote on purpose. Please update the code in your question if the missing quote was a transcription error. – zzzzBov Jun 19 '13 at 16:01
  • Also, please review [editing help](http://stackoverflow.com/editing-help) if you haven't already. – zzzzBov Jun 19 '13 at 16:02
  • Don't have a clue how that happened. I think i accidentally broke it up when pasting. It is fine in my code. It isn't the problem, either way. Thanks, anyway. – user2436606 Jun 19 '13 at 16:02
  • possible duplicate of [Javascript: Do I need to put this.var for every variable in an object?](http://stackoverflow.com/questions/13418669/javascript-do-i-need-to-put-this-var-for-every-variable-in-an-object) – Bergi Jun 19 '13 at 16:09

5 Answers5

4

You can't access the up and down values in the manner that you've written. You'd need to simply call down() from within the ArrowDir body, unless you've added those functions to the ArrowDir return value:

ArrowDir() {
  var up = ...;
  var down = ...;
  return {
    up: up,
    down: down
  };
}

Alternatively, if you're not using ArrowDir for anything other than encapsulating the up and down functions, you should just declare ArrowDir as an object, and call ArrowDir.up() and ArrowDir.down():

var ArrowDir = {
    up: function () {
        ...
    },
    down: function () {
        ...
    }
}
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
2

Assuming the missing quote after "#toggle is a typo, I'm not sure how you expect your code to work.

Here's how it runs, in prose:

  • Define a function ArrowDir.
  • When ready, attach a click handler
  • When clicked, call ArrowDir
    • In ArrowDir, define two local variables up and down, each with a function to do something.
    • There is no return statement, so return nothing
  • Call the down method of the "nothing" object. ERROR

See?

Try adding return {up:up,down:down}; to the end of your ArrowDir function.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
0

The var up and down you have defined inside ArrowDir are not accessible outside the scope of that function.

The simplest way you could fix this, if this is a one-time kind of function, is just to put the up/down behavior in your jQuery function, like this:

$(function () {
    if($("#toggle").onclick){
        $("#arrow").attr('src','up_arrow.jpg');
    } else {
        $("#arrow").attr('src','down_arrow.jpg');
    }
});

If you just want to namespace these functions for reusability you could make an object literal instead:

ArrowDir = {
  up: function(){
    $("#arrow").attr('src','up_arrow.jpg');
  },
  down: function(){
    $("#arrow").attr('src','down_arrow.jpg');
  }
};

Then you can call: ArrowDir.up() or ArrowDir.down() elsewhere.

For what it's worth, if your goal is just to namespace these functions for reusability, I would say the object literal syntax makes more sense to me.

Or, if you really want to do it as a function call, as Kolink has pointed out, the up/down functions need to be in the return value. You could write that like this...

function ArrowDir() {
  var up = function(){
    $("#arrow").attr('src','up_arrow.jpg');
  }
  var down = function(){
    $("#arrow").attr('src','down_arrow.jpg');
  }
  return {up:up,down:down};
}

Or like this...

function ArrowDir() {
  return {
    up: function(){
      $("#arrow").attr('src','up_arrow.jpg');
    },
    down: function(){
      $("#arrow").attr('src','down_arrow.jpg');
    }
  };
}

Now calling ArrowDir().down() should work.

Andrew
  • 42,517
  • 51
  • 181
  • 281
0

ArrowDir().down() here's your problem. Just because you define a variable in the ArrowDir function doesn't make it a method/property of it. You have to use Prototype Inheritance.

EDIT:

//Something like this:
ArrowDir.prototype.down = function() {
    //Do stuff
}

Now you can call ArrowDir.down(). Doing this extends the properties (things it can do) of the object ArrowDir. You're adding a method to it.

Jonny Sooter
  • 2,417
  • 1
  • 24
  • 40
0

You can create the object this way. In your function you are creating them insdied the scope of itself. SO it is not accessible outside.

function ArrowDir() {


}
ArrowDir.prototype.up = function () {
    $("#arrow").attr('src', 'up_arrow.jpg');
};

ArrowDir.prototype.down = function () {
    $("#arrow").attr('src', 'down_arrow.jpg');
}

and access it as

$(function () {
    if($("#toggle").onclick){
      var arrow =  new ArrowDir(); // call the constructor to create a new instance
      arrow.down(); // invoke the method
    };
});
PSL
  • 123,204
  • 21
  • 253
  • 243