if/else statement not registering if - javascript

My code seems to log the if statement as false, even though if I console.log the conditions it returns as true. Why is it doing that? (the code , that is not working is indicated by error not bypassing.)
function StaffMember(name,discountPercent){
this.name = name;
this.discountPercent = discountPercent;
}
function Stock(item){
this.item = item;
}
//Global Variables
var staffMembers = {};
var sally = new StaffMember("Sally",0.05);
staffMembers['sally'] = sally;
var bob = new StaffMember("Bob",0.10);
staffMembers['bob'] = bob;
var me = new StaffMember("Aaron",0.20);
staffMembers['me'] = me;
//item variables
var eggs = new Stock("Eggs");
var milk = new Stock("Milk");
var magazine = new Stock("Magazine");
var chocolate = new Stock("Chocolate");
//item Objects
var Stock = {};
Stock['eggs'] = eggs;
Stock['milk'] = milk;
Stock['magazine'] = magazine;
Stock ['chocolate'] = chocolate;**
var cashRegister = {
total:0,
lastTransactionAmount: 0,
add: function(itemCost){
this.total += (itemCost || 0);
this.lastTransactionAmount = itemCost;
},
scan: function(item,quantity){
switch (item){
case "eggs": this.add(0.98 * quantity); break;
case "milk": this.add(1.23 * quantity); break;
case "magazine": this.add(4.99 * quantity); break;
case "chocolate": this.add(0.45 * quantity); break;
}
return true;
},
voidLastTransaction : function(){
this.total -= this.lastTransactionAmount;
this.lastTransactionAmount = 0;
},
// Create a new method applyStaffDiscount here
applyStaffDiscount : function(employee){
this.total -= this.total*(employee.discountPercent);
}
};
$(document).ready(function(){
$('#target2').hide();
$('#check').on('click', function(e){
e.preventDefault();
var item = $('#item').val();
var quantity = $('#quantity').val();
var staff = $('#staff').val();
cashRegister.scan(item, quantity);
//ERROR IN CODE NOT BYPASSING
if(item === Stock['item'] && quantity > 0) {
cashRegister.scan(item, quantity);
}
///
else {
alert("This Item Does Not Exist!");
}
if(staff.length > 0 && typeof staffMembers[staff] !='undefined'){
cashRegister.applyStaffDiscount(staffMembers[staff]);
}
var output = document.getElementById("result");
result.innerHTML = 'Your bill is ' + cashRegister.total.toFixed(2);
$('#target2').fadeIn(5000)
// .animate({opacity: 0.5}, 3000)
.fadeOut(5000);
});
$('#target').submit(function(){
var info = $(this).serializeJSON();
console.log(info);
var data = JSON.parse('[info]');
console.log(data);
return false;
});
});

Stock['item'] is going to return undefined because Stock['item'] is not declared. You declare Stock['milk'], Stock['magazine'],Stock['eggs'], and Stock['chocolate'], but not Stock['item']. If you were trying to use it as a variable, you should remove the quotes.
You are also overwriting your "Stock" function with a "Stock" object, which is not causing trouble right now but it could cause issues later down the line. You should rename those to be different if possible.
Try using Stock[item] !== undefined && quantity > 0 in place of your current if expression

You did not post your HTML or a working fiddle, but my guess is your if statement should be:
if(item === Stock[item] && quantity > 0) {
cashRegister.scan(item, quantity);
}

Stock['item'] returns undefined as you're not calling it either with an object context like obj.Stock() or after using bind or call, so this is undefined. It's not returning anything either, so no assignment is made. I'm assuming $('#item').val() also. $('#item') is most likely null, triggering a runtime error and stopping your if sentence.

Related

Object function not working in JS

This is a function for a simple shopping app (kinda) thing that I coded to work on my JS skills, considering my elementary experience in it. But everything works except for one thing:
The applyStaffDiscount function doesn't seem to work. Everytime I try to apply an employee discount, the program just returns the same original value that was present before trying to apply the discount. Please help and also let me know how I can improve this program.
function StaffMember(name, discountPercent) {
this.name = name;
this.discountPercent = discountPercent;
}
var sally = new StaffMember("sally", 5);
var bob = new StaffMember("bob", 10);
var arhum = new StaffMember("arhum", 20);
var cashRegister = {
total: 0,
lastTransactionAmount: 0,
add: function(itemCost) {
this.total += (itemCost || 0);
this.lastTransactionAmount = itemCost;
},
scan: function(item, quantity) {
switch (item) {
case "eggs": this.add(0.98 * quantity); break;
case "milk": this.add(1.23 * quantity); break;
case "magazine": this.add(4.99 * quantity); break;
case "chocolate": this.add(0.45 * quantity); break;
}
return true;
},
voidLastTransaction: function() {
this.total -= this.lastTransactionAmount;
this.lastTransactionAmount = 0;
},
applyStaffDiscount: function(employee) {
this.total -= (this.total * (employee.discountPercent/100))
}
};
var cont = confirm("Are you ready to shop?")
while (cont) {
var user = ("Choose your function: A to Add Item, ED for Employee Discount, VT to Void Transaction or just X to Close")
var askUser = prompt(user).toUpperCase()
if (askUser === "A") {
var itemName = prompt("What item would you like?", "Eggs, Milk, Magazine, Chocolate").toLowerCase()
var itemNum = prompt("How many?")
cashRegister.scan(itemName, itemNum)
var cont = confirm("Your total bill is $" + cashRegister.total.toFixed(2) + ". Would you like anything else?")
}
else if (askUser === "ED") {
var name1 = prompt("Please enter you name").toLowerCase()
cashRegister.applyStaffDiscount[name1]
alert("Your total bill is $" + cashRegister.total.toFixed(2) + ".")
}
else if (askUser === "VT") {
cashRegister.voidLastTransaction()
alert("Your previous transaction has been voided. Your total bill is $" + cashRegister.total.toFixed(2) + " now.")
}
else if (askUser === "X") {
cont = false
}
if (cont === false) {
alert("We hope you had a good time. have a nice day!")
}
}
calling applyStaffDiscount should be done as shown below
cashRegister.applyStaffDiscount(name1);
Then inside applyStaffDiscount function, it should be accessed as below
this.total -= (this.total * (window[employee].discountPercent/100))
You didn't call the function in here:
cashRegister.applyStaffDiscount[name1]
Try it with something like this:
cashRegister.applyStaffDiscount(name1);

Debugging a push method in Javascript with an object

I am a beginner at js and have a project due by the end of day. I have to display an array with temps added and have set up an object to hold this array. My problem is that the message won't display and the for statement doesn't increment. When passed through both the var i and count come back undefined. I know there is a lot missing from this code but at this point I have tried to stream line it so that I can debug this issue. The date I will deal with later.
Here is my code:
var temps = [];
function process() {
'use strict';
var lowTemp = document.getElementById('lowTemp').value;
var highTemp = document.getElementById('highTemp').value;
var output = document.getElementById('output');
var inputDate = (new Date()).getTime();
var temp = {
inputDate : inputDate,
lowTemp : lowTemp,
highTemp : highTemp
};
var message = '';
if (lowTemp == null) {
alert ('Please enter a Low Temperature!');
window.location.href = "temps.html";
} else if (highTemp == null) {
alert ('Please enter a High Temperature!');
window.location.href = "temps.html";
} else {
lowTemp = parseFloat(lowTemp, 10);
highTemp = parseFloat(highTemp, 10);
}
if (temp.value) {
temps.push(temp.inputDate, temp.lowTemp, temp.highTemp)
var message = '<h2>Temperature</h2><ol>';
for (var i = 0, count = temps.length; i < count; i++) {
message += '<li>' + temps[i] + '</li>'
}
message += '</ol>';
output.innnerHTML = message;
}
return false;
}
function init() {
'use strict';
document.getElementById('theForm').onsubmit = process;
}
window.onload = init;
Here is my new code:
var temps = [];
function process() {
'use strict';
var lowTemp = document.getElementById('lowTemp').value;
var highTemp = document.getElementById('highTemp').value;
var output = document.getElementById('output');
var inputDate = (new Date()).getTime();
var temp = {
inputDate : inputDate,
lowTemp : lowTemp,
highTemp : highTemp
};
var message = '';
if (lowTemp == null) {
alert ('Please enter a Low Temperature!');
window.location.href = "temps.html";
} else if (highTemp == null) {
alert ('Please enter a High Temperature!');
window.location.href = "temps.html";
} else {
lowTemp = parseFloat(lowTemp, 10);
highTemp = parseFloat(highTemp, 10);
}
if (temp.value) {
temps.push(temp.inputDate, temp.lowTemp, temp.highTemp)
var message = '<h2>Temperature</h2><ol>';
for (var i = 0, count = temps.length; i < count; i++) {
message += '<li>' + temps[i] + '</li>'
}
message += '</ol>';
output.innnerHTML = message;
}
return false;
}
function init() {
'use strict';
document.getElementById('theForm').onsubmit = process;
}
window.onload = init;
There are some big issues with your code:
You should never compare anything to NaN directly. The correct comparison should be:
if (isNaN(lowTemp)) {
You're using curly braces when not needed. You should remove both curly braces:
{window.location.href = "temps.html";}
The function parseFloat expects only one parameter: the string to be converted. You're probably confusing it to parseInt which expects both the string and the radix of the conversion.
You're using the temp's property value, but you have never setted it, so, the condition where you check if it exists will always return false, and the push method that you want to debug will never be called, since it's inside that if statement.
Finally, you're closing a li tag at the end, but you have never opened it. You should probably be closing the ol tag you have opened in the begining.
The rest of your code seems pretty OK for me.
Talking about debugging, you should read the Google Chrome's Debugging Javascript Tutorial.

localStorage loadVote when refresh page (broken)

I cannot show voteUp/Down when I refresh page, because if I do voteUp/Down(+1 or -1) and refresh page, this return voteUp/Down (0) again. In this past I was using JSON, but the community recommended without JSON. So I have it, in this moment. Thanks.
var voteUp = document.getElementById('vote-up');
var voteDown = document.getElementById('vote-down');
var handUp = once(function() {
var total = Number(voteUp.innerHTML);
total += 1;
voteUp.innerHTML = total;
saveVote();
});
voteUp.addEventListener('click', handUp);
var handDown = once(function() {
var total = Number(voteDown.innerHTML);
total -= 1;
voteDown.innerHTML = total;
saveVote();
});
voteDown.addEventListener('click', handDown);
function once(fn, context) {
var result;
return function() {
if(fn) {
result = fn.apply(context);
fn = null;
}
return result;
};
}
function saveVote() {
var votes = voteUp, voteDown;
localStorage.setItem('data', votes);
console.log('saveVote');
}
function loadVote() {
var votes = localStorage.getItem('data');
if(!votes){
return;
}
console.log(localStorage.getItem('data'));
}
loadVote();
var voteUp = document.getElementById('vote-up');
function handUp() {
var total = Number(voteUp.innerHTML);
total += 1;
voteUp.innerHTML = total;
}
voteUp.addEventListener('click',handUp,false);
It increments each one value by a click.
There's no such thing as an =+ operator, there is an += operator, however.
+=
Addition assignment.
Also, I'm pretty sure the typeof val is undefined since it's value is never defined in the argument passing of the method.
A variable which's type is undefined can certainly not contain a value which's a number (it's NaN) and thus the error message makes sense.

What is wrong with my javascript for-in loop

<!DOCTYPE html>
<html>
<body>
<script language="javascript" type="text/javascript">
//Definition of staff members (class)
function StaffMember(name,discountPercent){
this.name = name;
this.discountPercent = discountPercent;
}
//Creation of staff members (object)
var s121 = new StaffMember("Sally",5);
var b122 = new StaffMember("Bob",10);
var d123 = new StaffMember("Dave",20);
staffMembers = [s121,b122,d123];
//Creation of cash register (object)
var cashRegister = {
total:0,
lastTransactionAmount: 0,
//Add to the total (method)
add: function(itemCost){
this.total += (itemCost || 0);
this.lastTransactionAmount = itemCost;
},
//Retreive the value of an item (method)
scan: function(item,quantity){
switch (item){
case "eggs": this.add(0.98 * quantity); break;
case "milk": this.add(1.23 * quantity); break;
case "magazine": this.add(4.99 * quantity); break;
case "chocolate": this.add(0.45 * quantity); break;
}
return true;
},
//Void the last item (method)
voidLastTransaction : function(){
this.total -= this.lastTransactionAmount;
this.lastTransactionAmount = 0;
},
//Apply a staff discount to the total (method)
applyStaffDiscount: function(employee) {
this.total -= this.total * (employee.discountPercent / 100);
}
};
//Ask for number of items
do {
var numOfItems = prompt("How many items do you have?");
document.body.innerHTML = numOfItems;
if (isNaN(numOfItems)) {
i=0;
} else {
i=1;
}
} while (i===0);
//Ask for item and qty of item
var items = [];
var qtys = [];
for(var i=0;i<numOfItems;i++) {
var j=0;
do {
items[i] = prompt("What are you buying? (eggs, milk, magazine, chocolate)");
switch (items[i]) {
case "eggs" :;
case "milk" :;
case "magazine" :;
case "chocolate" : j=1; document.body.innerHTML = items[i]; break;
default : document.body.innerHTML = 'Item not reconized, please re-enter...'
; break;}
} while (j===0);
do {
qtys[i] = prompt("How many " + items[i] + " are you buying?");
document.body.innerHTML = qtys[i];
if (isNaN(qtys[i])) {
j=1;
} else {
j=0;
}
} while (j===1);
//Add to the sub-total
cashRegister.scan(items[i],qtys[i])
}
//Find out if it's a staff member & if so apply a discount
var customer;
var staffNo;
do {
customer = prompt("Please enter customer name or type 'staff'.");
document.body.innerHTML = customer;
if (customer === 'staff') {
staffNo = prompt("Please enter your staff number");
for (i in staffMembers) {
if (staffMembers[i] === staffNo) {
cashRegister.applyStaffDiscount(staffNo);
} else {
document.body.innerHTML = "Staff number not found";
};
}
}
i=1;
} while (i=0);
// Show the total bill
if (customer !== 'staff') {
document.body.innerHTML = 'Your bill is £'+cashRegister.total.toFixed(2)
+' Thank you for visiting ' +customer;
} else {
document.body.innerHTML = 'Your bill is £'+cashRegister.total.toFixed(2)
+' Thank you for visiting ' +staffNo;
};
</script>
</body>
</html>
What seems to be wrong with my code, it works but does not apply the staff discount, I feel the error is around;
for (i in staffMembers) {
if (staffMembers[i] === staffNo) {
cashRegister.applyStaffDiscount(staffNo);
} else {
document.body.innerHTML = "Staff number not found";
};
}
Can anybody help spot the error, I've been learning on CodeAcademy but have taken the final example further with checks on data entered. But I can't seem to see why this section is not working as it should when checked via 'http://www.compileonline.com/try_javascript_online.php'.
It turns out there is quite a lot wrong with your code. The key things you need to fix to get it "working" are the following:
First - you are asking for a "staff number", but your employee structure doesn't have space for that. You could modify the StaffMember as follows:
//Definition of staff members (class)
function StaffMember(name, number, discountPercent){
this.name = name;
this.number = number;
this.discountPercent = discountPercent;
}
//Creation of staff members (object)
var s121 = new StaffMember("Sally","s121",5);
var b122 = new StaffMember("Bob","b122",10);
var d123 = new StaffMember("Dave","d123",20);
staffMembers = [s121,b122,d123];
Now you have a "unique identifier" - I decided to give the employee the same number as the variable name, but that is not necessary.
Next, let's look at the loop you had: change it to
do {
customer = prompt("Please enter customer name or type 'staff'.");
document.body.innerHTML = customer;
if (customer === 'staff') {
staffNo = prompt("Please enter your staff number:");
for (i in staffMembers) {
if (staffMembers[i].number === staffNo) { // <<<<< change the comparison
cashRegister.applyStaffDiscount(staffMembers[i]); // <<<<< call applyStaffDiscount with the right parameter: the object, not the staff number
} else {
document.body.innerHTML = "Staff number not found";
};
}
}
i=1; // <<<<< I really don't understand why you have this do loop at all.
} while (i == 0); // <<<<< presumably you meant "while(i == 0)"? You had "while (i=0)"
There are many, many things you could do to make this better - but at least this will get you started. Complete "working" code (I may have made other edits that I forgot to point out - but the below is copied straight from my working space, and "works" - albeit rather flaky):
<!DOCTYPE html>
<html>
<body>
<script language="javascript" type="text/javascript">
//Definition of staff members (class)
function StaffMember(name, number, discountPercent){
this.name = name;
this.number = number;
this.discountPercent = discountPercent;
}
//Creation of staff members (object)
var s121 = new StaffMember("Sally","s121",5);
var b122 = new StaffMember("Bob","b122",10);
var d123 = new StaffMember("Dave","d123",20);
staffMembers = [s121,b122,d123];
//Creation of cash register (object)
var cashRegister = {
total:0,
lastTransactionAmount: 0,
//Add to the total (method)
add: function(itemCost){
this.total += (itemCost || 0);
this.lastTransactionAmount = itemCost;
},
//Retreive the value of an item (method)
scan: function(item,quantity){
switch (item){
case "eggs": this.add(0.98 * quantity); break;
case "milk": this.add(1.23 * quantity); break;
case "magazine": this.add(4.99 * quantity); break;
case "chocolate": this.add(0.45 * quantity); break;
}
return true;
},
//Void the last item (method)
voidLastTransaction : function(){
this.total -= this.lastTransactionAmount;
this.lastTransactionAmount = 0;
},
//Apply a staff discount to the total (method)
applyStaffDiscount: function(employee) {
this.total -= this.total * (employee.discountPercent / 100);
}
};
//Ask for number of items
do {
var numOfItems = prompt("How many items do you have?");
document.body.innerHTML = numOfItems;
if (isNaN(numOfItems)) {
i=0;
} else {
i=1;
}
} while (i===0);
//Ask for item and qty of item
var items = [];
var qtys = [];
for(var i=0;i<numOfItems;i++) {
var j=0;
do {
items[i] = prompt("What are you buying? (eggs, milk, magazine, chocolate)");
switch (items[i]) {
case "eggs" :;
case "milk" :;
case "magazine" :;
case "chocolate" : j=1; document.body.innerHTML = items[i]; break;
default : document.body.innerHTML = 'Item not reconized, please re-enter...'
; break;}
} while (j===0);
do {
qtys[i] = prompt("How many " + items[i] + " are you buying?");
document.body.innerHTML = qtys[i];
if (isNaN(qtys[i])) {
j=1;
} else {
j=0;
}
} while (j===1);
//Add to the sub-total
cashRegister.scan(items[i],qtys[i])
}
//Find out if it's a staff member & if so apply a discount
var customer;
var staffNo;
do {
customer = prompt("Please enter customer name or type 'staff'.");
document.body.innerHTML = customer;
if (customer === 'staff') {
staffNo = prompt("Please enter your number:");
for (i in staffMembers) {
if (staffMembers[i].number === staffNo) {
cashRegister.applyStaffDiscount(staffMembers[i]);
} else {
document.body.innerHTML = "Staff number not found";
};
}
}
i=1;
} while (i=0);
// Show the total bill
if (customer !== 'staff') {
document.body.innerHTML = 'Your bill is £'+cashRegister.total.toFixed(2)
+'<br> Thank you for visiting ' + customer;
} else {
document.body.innerHTML = 'Your bill is £'+cashRegister.total.toFixed(2)
+'<br> Thank you for visiting staff member ' +staffNo;
};
</script>
</body>
</html>
In every singe loop there is an element from stattMembers in i, not its position. So you don't get 0, 1, 2 in it but staffMembers[0], staffMembers[1], staffMembers[2]. You should think about this, maybe a simple for-loop is better in your case?
The problem lies in these lines
if (staffMembers[i] === staffNo) {
cashRegister.applyStaffDiscount(staffNo);
}
it should have been
if (i === staffNo) {
cashRegister.applyStaffDiscount(staffMembers[i]);
}
Since you are first validating for the existence of the index(no) of a staff, then i == staffNo should be the right condition.
cashRegister.applyStaffDiscount() expects an instance of a StaffMember so passing on to the staffMembers[i] object does the trick.

Getting TypeError: cannot call getNumber method of undefined

I am working on a simple blackjack program. I am completely new to javascript and am having trouble debugging my program. I keep getting the TypeError: cannot call getNumber method of undefined..... and i'm totally lost. I am trying to get the numerical value stored for each card but it appears thats the error is happening in my printHand() method inside the Hand class. When printing out the hand of two or more cards, I loop through each card in the hand calling cards[i].getNumber() where cards[] is the array of cards in each hand. Am i not referencing cards[] properly? I double checked to make sure my methods and variables were set to public but I still cannot figure out why getNumber() is being called on an undefined object. Is there something wrong with the way I am referencing this object?
Here is my code:
// Card Constructor
function Card (suit, number){
var the_suit = suit;
var the_number = number;
this.getNumber = function(){
return the_number;
};
this.getSuit = function(){
return the_suit;
};
this.getValue = function (){
// face cards
if(the_number > 10){
return 10;
// aces
} else if (the_number < 2){
return 11;
// other cards
} else {
return the_number;
}
};
}
function deal (){
// get card suit
var rand1 = Math.floor(Math.random ( ) * 4 + 1);
// get car number
var rand2 = Math.floor(Math.random ( ) * 13 + 1);
var newCard = new Card(rand1, rand2);
}
function Hand (){
// create two cards for initial hand
var card1 = deal();
var card2 = deal();
// store cards in array
var cards = [card1,card2];
// getter
this.getHand = function (){
return cards;
};
// get the score
this.score = function(){
var length = cards.length;
var score = 0;
var numAces = 0;
for(i = 0; i < length; i++){
if (cards[i].getValue() === 11 ){
numAces++;
}
score += cards[i].getValue();
}
while(score > 21 && numAces !== 0){
sum -= 10;
numAces--;
}
};
this.printHand = function(){
var length = cards.length;
for(i=0; i< length; i++){
var string = string + cards[i].getNumber() + " of suit " + cards[i].getSuit() + ", ";
}
return string;
};
this.hitMe = function(){
var newCard = deal();
cards.push(newCard);
}
}
function playAsDealer(){
var newHand = new Hand();
while(newHand.score < 17){
newHand.hitMe();
}
return newHand;
}
function playAsUser(){
var newHand = new Hand();
var choice = confirm("Current hand: "+ newHand.printHand() + ": Hold (Ok) or Stand(Cancel)");
while(choice){
newHand.hitMe();
choice = confirm("Current hand: "+ newHand.printHand() + ": Hold (Ok) or Stand(Cancel)");
}
}
function declareWinner(user, dealer){
//user wins case
if (user.score > dealer.score){
console.log("You are the Champion!");
}
// tie game
else if(user.score===dealer.score){
console.log("Tied!");
}
else{
console.log("Loser!!");
}
}
function playGame (){
var user = playAsUser();
var dealer = playAsDealer();
console.log("User's Hand: " + user.printHand());
console.log("Dealer's Hand: " + dealer.printHand());
declareWinner();
}
playGame();
You don't return the card object in the function "deal":
should be:
function deal (){
// get card suit
var rand1 = Math.floor(Math.random ( ) * 4 + 1);
// get car number
var rand2 = Math.floor(Math.random ( ) * 13 + 1);
var newCard = new Card(rand1, rand2);
return newCard;
}
There are a few probs, but to get you started:
The error i got was "TypeError: cards[i] is undefined". Since you are calling your deal() function like this:
var card1 = deal();
You'll need to return the card in the deal func, so change
var newCard = new Card(rand1, rand2);
to
return new Card(rand1, rand2);
You'll also need to convert : cards[i].getNumber() to a string when you print the hand

Categories

Resources