0

I am trying to pass the values I get from my form into a constructor function called Robot(); I have no problem accomplishing this in the console by passing in the arguments myself. for ex: var travis = new Robot("Travis","Blue","medium"); if i were to enter something like travis.speed it would return 1 as expected.

but when I try using my form on the website to do so and test it out the console says Travis is not defined.

I feel like I am doing everything correct, but apparently I am not. If someone could please help me out I would be much appreciative.

my script.js:

var $canvas = $("canvas");
var ctx = $canvas[0].getContext("2d");

function Robot(name, color, robotBuild){
    this.name = name.toLowerCase();
    this.robotBuild = 'medium';
    this.health = 100;
    this.speed = 1;
    this.strength = 1;
    this.powerState = false;
    this.maxStrength = 100;
    this.minStrength = 1;
    this.maxSpeed = 10;
    this.minSpeed = 1;
    this.maxHealth = 100;
    this.minHealth = 0;
    this.points = 0;
    //ROBOT POSITION VALUES
    this.posX = 0;
    this.posY = 0;
    //ROBOT PHYSICAL PROPERTIES
    this.robotWidth = 10;
    this.robotHeight = 10;
    this.robotColor = color.toLowerCase();
}
Robot.prototype.draw = function(){
    ctx.beginPath();
    ctx.rect(this.posX, this.posY, this.robotWidth, this.robotHeight);
    ctx.fillStyle = this.robotColor;
    ctx.fill();
    ctx.closePath();
    this.powerState = true;
};
Robot.prototype.power = function(powerState){
    powerState.toLowerCase();
    if(powerState === "on"){
        this.powerState = true;
    }else if(powerState === "off") {
        this.killRobot();
    }else {
        console.log("Input must be a value of 'on' or 'off'.");
    }
};

Robot.prototype.killRobot = function(){
    this.powerState = false;
    ctx.clearRect(0, 0, $canvas.width, $canvas.height);
    console.log(this.name + " the robot is now dead.");
};

Robot.prototype.setStrength = function(num){
    if( num < this.minStrength || num > this.maxStrength ){
        return 'error: strengthLevel can not be less than 0 or greater than 100.';
    }else if(isNaN(num)){
        return 'error: Input must be a numbered value.';
    }else {
        this.strength = num;
        return this.strength;
    }
};
Robot.prototype.incHealth = function(num){
    if(isNaN(num)){
        console.log('error: Input must be a numbered value.');
    }
    else if((this.health + num) >= this.maxHealth ){
        this.health = 100;
        console.log('You have reached full Health, use it wisely.');
    }else {
        this.health += num;
        console.log('Your Health is increasing.');
        return this.health;
    }
};

Robot.prototype.decHealth = function(num){
    if(isNaN(num)){
        console.log('error: Input must be a numbered value.');
    }
    else if( (this.health - num) <= this.minHealth){
        this.powerState = false;
        this.health = 0;
        this.killRobot();
        return this.health;
    }else {
        this.health -= num;
        console.log('You are loosing health:(');
        return this.health;
    }
};

Robot.prototype.incSpeed = function(num){
    if( (this.speed + num) < this.minSpeed || (this.speed + num) > this.maxSpeed ){
        console.log('error: Speed Level can not be less than 0 or greater than 100.');

    }else if(isNaN(num)){
        console.log('error: Input must be a numbered value.');

    }else {
        this.speed += num;
        return this.speed;
    }
};

Robot.prototype.decSpeed = function(num){
    if( (this.speed - num) < this.minSpeed || (this.speed - num) > this.maxSpeed ){
        console.log('error: Speed Level can not be less than 0 or greater than 100.');

    }else if(isNaN(num)){
        console.log('error: Input must be a numbered value.');

    }else {
        this.speed -= num;
        return this.speed;
    }
};

Robot.prototype.incStrength = function(num){
    if( (this.strength + num) < this.minStrength || (this.strength + num) > this.maxStrength ){
        console.log('error: strengthLevel can not be less than 0 or greater than 100.');

    }else if(isNaN(num)){
        console.log('error: Input must be a numbered value.');

    }else {
        this.strength += num;
        return this.strength;
    }
};

Robot.prototype.decStrength = function(num){
    if( (this.strength - num) < this.minStrength || (this.strength - num) > this.maxStrength ){
        console.log('error: strengthLevel can not be less than 0 or greater than 100.');

    }else if(isNaN(num)){
        console.log('error: Input must be a numbered value.');

    }else {
        this.strength -= num;
        return this.strength;
    }
};

//MOVING ROBOT POSITION FUNCTIONALITY
Robot.prototype.position = function(){
    this.position = {
        posX: this.posX,
        posY: this.posY
    };
    return this.position;
};

Robot.prototype.moveUp = function(y){
    if(this.powerState === true){
        this.posY += y;
        return this.posY;
    }else {
        console.log("Robot is dead and can not move.");
    }

};

$(".createRobot").click(function(){
    $("#robotForm").toggle();
});

$("#submitRobot").click(function(e){
    e.preventDefault();
    var robotName = $("#robotName").val();
    var robotColor = $("#robotColor").val();
    var robotBuild = $("#robotBuild option:selected").text();
    console.log(typeof robotName); // should return "string"
    console.log(robotName + ", " + robotColor + ", " + robotBuild);
    var robot = new Robot(robotName, robotColor, robotBuild);
});

HTML form:

<div id="robotForm">
   <h4>Create your robot with the form below:</h4>
   <p><label>Your Robot's name:<input class="robotName" type="text" name="name" value="" placeholder="Robot's name"></label></p>
   <p><label>Your Robot's color:<input class="robotColor" type="text" name="color" value="" placeholder="Robot's color"></label></p>
   <p><label>Your Robot's build type:
   <select class="robotBuild" name="robotBuild">
     <span>Select your robot's build type</span>
     <option name="small" value="small">Small Robot Build</option>
     <option name="medium" value="medium">Medium Robot Build</option>
     <option name="large" value="large">Large Robot Build</option>
   </select>
   </label>
   </p>
   <button class="submitRobot" type="submit">Submit your Robot</button>
   </div>
Travis Michael Heller
  • 1,210
  • 3
  • 16
  • 34
  • 3
    What are you expecting the `return robot;` to actually return to? Where is your logging that is logging undefined? – James Thorpe Oct 30 '15 at 19:56
  • 3
    show us your tests, because the problem is that in your click event you are returning your Robot instance.. to nowhere – Gonzalo.- Oct 30 '15 at 19:56
  • You are not actually testing your robot object here, you should try doing something like `console.log(robot.name)` and see what happens. – AGE Oct 30 '15 at 19:57
  • 1
    `Travis` is not defined because you're not defining it (at least not in the code you've posted). Maybe use `Travis = new Robot(...)` instead of `var robot = ...`? – pawel Oct 30 '15 at 19:59
  • i am not really looking for anything from the return, honetly i don't know why i have that in my code. after i hit submit on my form i type this: name.speed or name.health but when i do it returns as undefined – Travis Michael Heller Oct 30 '15 at 20:00
  • I am bascialy wanting to do this var robot1 = new Robot("travis","green","large"); and have it create a new instance of Robot. but instead of doing it in the console i am trying to do it dynamically using the inputs from my form. – Travis Michael Heller Oct 30 '15 at 20:03
  • 2
    You're creating the `Robot` instance in the event listener scope. If you want to use it outside the event listener then define a variable in outer scope and assign the instance to it, or just go with `window.robot1 = new Robot()`. – pawel Oct 30 '15 at 20:07
  • Pawel would it return undefined if i used Travis = new Robot since Travis is not defined as a variable? – Travis Michael Heller Oct 30 '15 at 20:08
  • @TravisMichaelHeller it would work and omitting the `var` keyword would create a global variable. But it would be better to be explicit and create `window.Travis = new Robot()` (this way you're signalling to your future self that you want a global, not that you forgot `var` by mistake). – pawel Oct 30 '15 at 20:10
  • @James: I am wanting to create a new instance of Robot dynamically using the values from the submitted form. How would i accomplish this? sorry i am new at this and trying to learn by creating this small project. – Travis Michael Heller Oct 30 '15 at 20:10
  • I would point you to http://ejohn.org/blog/simple-class-instantiation/ and then please review the answers to: http://stackoverflow.com/questions/7892884/simple-class-instantiation\ and then this one: http://stackoverflow.com/questions/9057816/john-resigs-simple-class-instantiation-and-use-strict – Mark Schultheiss Oct 30 '15 at 20:30
  • your jQuery code gets id's and your markup uses classes. – Mark Schultheiss Oct 30 '15 at 21:00
  • Sample fiddle with the use of the noted: http://jsfiddle.net/tqwjvn5o/ – Mark Schultheiss Oct 30 '15 at 21:10

5 Answers5

1

$(".submitRobot").click(function(e){
    e.preventDefault();
    var robotName = $(".submitRobot").val();
    var robotColor = $(".robotColor").val();
    var robotBuild = $(".robotBuild").val();
    console.log(typeof(robotName));
    console.log(robotName + ", " + robotColor + ", " + robotBuild);
    var robot = new Robot(robotName, robotColor, robotBuild);
    $("#res").html(robot.speed);
 return robot;
 
});

function Robot(name, color, robotBuild){
 
    this.name = name.toLowerCase();
    this.robotBuild = 'medium';
    this.health = 100;
    this.speed = 1;
    this.strength = 1;
    this.powerState = false;
    this.maxStrength = 100;
    this.minStrength = 1;
    this.maxSpeed = 10;
    this.minSpeed = 1;
    this.maxHealth = 100;
    this.minHealth = 0;
    this.points = 0;
    //ROBOT POSITION VALUES
    this.posX = 0;
    this.posY = 0;
    //ROBOT PHYSICAL PROPERTIES
    this.robotWidth = 10;
    this.robotHeight = 10;
    this.robotColor = color.toLowerCase();
 return this;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type=name class='submitRobot' value='Travis'>
<input type=text class='robotColor' value='Blue'>
<input tyle=text class='robotBuild' value='medium'>

<input type=button class='submitRobot' value=submitRobot>

<div id=res></div>

This shows 1 when I run it

Lucky Chingi
  • 2,248
  • 1
  • 10
  • 15
  • i see that it places the correct response in the DOM why am i not able to to type robot.speed in the console and get that same response without it saying robot is not defined? am i trying to do something out of scope? – Travis Michael Heller Oct 30 '15 at 20:34
  • have you added return to the constructor function? – Lucky Chingi Oct 30 '15 at 20:43
  • haha i saw that you added that and i did add that to my script. thank you for pointing that out. i ended up adding the return this at bottom of constructor function as well as adding var robot; at the top of my script so that it becomes a global variable. it works now. – Travis Michael Heller Oct 30 '15 at 20:45
1

I do not know what do you want to do with the return, but I think it does not matter.

You have to make sure that the code that contains your Robot-class is executed before the event handler executes (i.e. by loading the JavaScript file before any other than jQuery).

Also, the scope of Robot is not correct. I am not using that type of declaration anymore, as it does everything but not what you want. Instead, it would be better to assign the class to the window object directly, by doing:

window.Robot = function(...) { ... };

This way, the Robot class is globally available.

Fabian

Fabian Damken
  • 1,477
  • 1
  • 15
  • 24
  • I figured out the problem. my variable robot was only in scope within the submit function and not globally. so when i type robot.speed in the console it is not defined because it is not in the global scope. thank you. although i didn't use window.function i just created the robot variable at the top of my script so that is is global. – Travis Michael Heller Oct 30 '15 at 20:43
0

You are extracting the jQuery information from your robotName robotColor robotBuild using the val() function, when you should be using the text() function. When you try to build your object and extract information from it, you end up with blank data or even an erroneous reference.

AGE
  • 3,752
  • 3
  • 38
  • 60
0

Your function $(".submitRobot").click(function(e) etc is jQuery.
It adds a clickhandler to all DOM nodes (HTML) of class "submitRobot".
Whenever user clicks on such a DOM node, it is taking val() from other DOM nodes of class "robotName" etc. NB: there could be more than 1 of those in your HTML, probably better to use IDs instead of Class selectors.

Then it creates an entity robot, which is of the class Robot you constructed.

Issue here is:

The variable Travis does not exist (there is a variable robot, and robot.name could have the string content of "Travis".

And possibly the clickhandler function does not fetch the values from your form, so robot.name could be undefined. Or maybe robot does not even exist, if your clickHandler function never gets called, or never gets to the point where it can create the robot.

If you change your class=... to id=... in your HTML, than this could work:

$("#submitRobot").click(function(e){
    e.preventDefault();
    var robotName = $("#robotName").val();
    var robotColor = $("#robotColor").val();
    var robotBuild = $("#robotBuild option:selected").text();
    console.log(typeof robotName); // should return "string"
    console.log(robotName + ", " + robotColor + ", " + robotBuild);
    var robot = new Robot(robotName, robotColor, robotBuild);
});

UPDATE: The var robot is scope-bound to the clickhandler. So you cannot access it from the console, because console is outside that scope. To solve, define a global variable var robot; in your javascript (global = somewhere outside of any functions or blocks {}).
And change the last line of your clickhandler to:

robot = new Robot(robotName, robotColor, robotBuild);

Then you should be able to access robot.name and other parameters from your console.

wintvelt
  • 13,855
  • 3
  • 38
  • 43
  • I edited my comment to show my HTML form. hope this helps. – Travis Michael Heller Oct 30 '15 at 20:15
  • I can share the rest of my javascript code if that will help explain what i am trying to do. The whole purpose of this project is to better understand Object inheritance and prototypes. – Travis Michael Heller Oct 30 '15 at 20:16
  • I am wanting to create a simple game using Canvas and javascript. – Travis Michael Heller Oct 30 '15 at 20:19
  • i tried the function edit you made as well as changed my inputs to ID's and when i type robot.speed in the console is says undefined – Travis Michael Heller Oct 30 '15 at 20:29
  • @TravisMichaelHeller this issue relates to @fabian's answer: the `var robot` is scope-bound to the clickhandler. So you cannot access it from console, because console is outside that scope. See edit. – wintvelt Oct 30 '15 at 20:48
  • Not sure who to give the accepted answer as i used a little bit of everyone's advice and help. thank you everyone for your help. I made the var robot global by placing at top of script, i added return this; in my constructor function and made my form use ID's in the inputs. – Travis Michael Heller Oct 30 '15 at 20:49
0
Your code works for me.
http://jsfiddle.net/awakeningbyte/2wroeuL2/2/

However, I noticed you define the variable as var travis, while you say "Travis is not defined". is this a typo?

George Chen
  • 6,592
  • 5
  • 21
  • 23