Why does my JavaScript function work but displays "undefined" right after? - javascript

Let me preface this by saying I'm a beginner in the world of programming so please excuse my ignorance.
I wrote a simple script for calculating discounts that work, however it displays "undefined" after I execute the code.
let price = prompt("What is the total cost? ");
function total() {
if (price > 250) {
var result = price * discount;
var cost = price - result;
console.log("your total cost will be " + cost);
} else {
console.log("your total cost will be " + price)
}
}
discount = 0.15
console.log(total());
However, when I switch the console.log statements to return statements the undefined message goes away.
let price = prompt("What is the total cost? ");
function total() {
if (price > 250) {
var result = price * discount;
var cost = price - result;
return ("your total cost will be " + cost);
} else {
return ("your total cost will be " + price)
}
}
discount = 0.15
console.log(total());
Why is this? It's confusing me and I don't understand why I'm getting the undefined message.

On the two lines marked "1" you are outputting strings to the console.
In the line marked "2" you are outputting the results of the function total() to the console. But, in your code there is no "result" because you didn't return a value. (Therefore, the value of total() was undefined).
However, when you replaced the lines marked "1" with return(..) in your second code, the total function returned a value (the string). So when you tried to console.log the value of the total() function, it worked.
To look at it another way... if you had a function like this:
function example(){
let value1 = 5+5;
let value2 = 1+1;
}
What would be the value of example()? Nothing -- or undefined. Because how would the function know if you wanted value1, value2 or some combination of the two?
You use the "return" statement to let the function know what is the final value.
function example(){
let value1 = 5+5;
let value2 = 1+1;
return value1*value2;
}
Now the function returns the value (in this case 20).

Related

Show error alert if value is outside range on button press

I have a 'calculate' button that takes the quantity entered and multiplies it by the value of an item. JS is below:
function calculate() {
var totalPrice=0;
var price = document.getElementById("itemprice").innerHTML;
var quantity = document.getElementById("quantity").value;
totalPrice=price * quantity;
document.getElementById("totalamount").innerHTML="$" + totalPrice;
//document.write(price * quantity)
}
The above works perfectly for the calculate button. I'm looking to add to this
What I want to also achieve is adding an alert pop up should the "totalprice" result equals zero, a negative number, or NaN (if someone inputs a letter into the quantity box).
So adding to the above something like this:
if ("totalPrice" < 1, NaN)
alert (Please Enter valid quantity)
But I just don't seem to be able to make it work.
totalPrice is variable, if you put it in quotes its a string
if you need 2 conditions in if use || an or operator in your case. Also read: javascript multiple OR conditions in IF statement
Read here how to check for NaN
totalPrice = "not a number"
if (isNaN(totalPrice) || totalPrice < 1) {
alert("Please Enter valid quantity")
}
So you should use:
function calculate() {
var totalPrice = 0;
var price = document.getElementById("itemprice").innerHTML;
var quantity = document.getElementById("quantity").value;
totalPrice = price * quantity;
if (isNaN(totalPrice) || totalPrice < 1) {
alert("Please Enter valid quantity")
} else {
document.getElementById("totalamount").innerHTML = "$" + totalPrice;
}
}

How to get a JavaScript factorial programs' loop to show the working used?

Hello there I have been challenged to write a program in JavaScript despite not really knowing much about it that asks the user for a number and then calculates the factorial of that number. I used already asked questions and managed to get the calculation to work but couldn't get the required output. I have to get it in the following output without using any fancy libraries or extra variables/arrays (which I can't think of how to do) :
(assuming user input is 5):
The factorial of 5 is 5*4*3*2*1=120
OR
5! is 5*4*3*2*1=120
Here is the code I've got so far:
//prompts the user for a positive number
var number = parseInt(prompt("Please enter a positive number"));
console.log(number);
//checks the number to see if it is a string
if (isNaN(number)) {
alert("Invalid. Please Enter valid NUMBER")
}
//checks the number to see if it is negaive
else if (number < 0) {
alert("Please Enter valid positive number");
}
//if a positive integer is entered a loop is started to calculate the factorial of the number the user entered
else {
let factorial = 1;
for (count = 1; count <= number; count++) {
factorial *= count;
}
//Sends the inital number back to the user and tells them the factorial of that number
alert("The factorial of " + number + " is " + factorial + ".");
}
I know there are many similar questions to this as I looked around and used them to help me get this far but it is getting the output into the required format that I'm struggling with. I am told it is possible with a loop but don't know where to begin implementing that and I'm only allowed to use that solution.
Unfortunately this is part of a larger program in the challenge and I can only use the following variables:
Number (variable initialised as 0 to hold user input)
Factorial (variable initialised to 1 to hold value of calculated factorial)
Count (variable to hold number of times loop is executed for performing factorial calculation)
Probably you just need to build a string in that loop (on top of calculating the actual value):
let input=parseInt(prompt("Number?"));
let output="";
let result=1;
for(let i=input;i>1;i--){
result*=i;
output+=i+"*";
}
console.log(input+"! is "+output+"1="+result);
The "no-array clause" in your task presumably means that you are not supposed to build an array and use join() on it, like
let arr=[1,2,3,4,5];
console.log(arr.join("*"));
I have updated your code mainly here, Also make sure you are using the same variable num in your code and not number:
let factorials = [];
let result = 1;
for (count = num; count >= 1; count--) {
result *=count;
factorials.push(count);
}
//prompts the user for a positive number
var num = parseInt(prompt("Please enter a positive number"));
console.log(num);
//checks the number to see if it is a string
if (isNaN(num))
{
alert("Invalid. Please Enter valid NUMBER")
}
//checks the number to see if it is negaive
else if (num < 0)
{
alert("Please Enter valid positive number");
}
//if a positive integer is entered a loop is started to calculate the factorial of the number the user entered
else {
let factorials = [];
let result = 1;
for (count = num; count >= 1; count--) {
result *=count;
factorials.push(count);
}
//Sends the inital number back to the user and tells them the factorial of that number
alert("The " + num + "! is " + factorials.join('*') + " is " + result + ".");
}

How to deal with "undefined" and "NaN" in simple javascript calculations?

So two dropdowns and a few javascript functions to choose a price and set a country (which comes with a tax rate). Then display the price + tax rate = total to the user on the payment form.
If a price and a country(tax rate) are selected, the javascript and the sums work, thusly:
£49.99 + 10% VAT = £54.99
If a price but no country(tax rate) are selected, this happens:
Total: £49.99 + undefined% VAT = £NaN
And if neither a price or a country(tax rate) are selected, then we get:
£undefined + undefined% VAT = £NaN
So the question is: how do we deal with those ugly errors from javascript? What's the javascript way to deal with if/else for undefined and NaN?
Thanks.
UPDATE 2: the NaN check works, but where do I put the undefined check. Have added the TaxPrice function so you can see where it is coming from.
// First grab the tax rate from a drop down
function TaxPrice()
{
var taxprice=0;
var theForm = document.forms["payment-form"];
var selectedrate = theForm.elements["country_vat"];
taxprice = tax_rates[selectedrate.value];
return taxprice;
}
// Then calculate the total, including the NaN checks
function calculateTotal()
{
var TaxRate = TaxPrice() / 100;
var TotalPrice = PlanPrice() + (TaxRate * PlanPrice());
var TotalTax = (TaxRate * PlanPrice())
if(isNaN(TotalPrice)) {
// check NaN
TotalPrice = 0
}
if(isNaN(TotalTax)) {
// check NaN
TotalTax = 0
}
//display the price
var divobj = document.getElementById('p');
divobj.innerHTML = "£" + PlanPrice();
//display the tax rate
var divobj = document.getElementById('r');
divobj.innerHTML = "£" + TotalTax.toFixed(2) + " (" + TaxPrice() + "% VAT)";
//display the total
var divobj = document.getElementById('t');
divobj.innerHTML = "£" + TotalPrice.toFixed(2);
}
Check specifically for undefined with
if(typeof price === "undefined"){}
Check specifically for NaN with
if(isNaN(price)){}
Generally you can also simply do
if(price){}
Where the inside of the if statement will return false if price is NaN, undefined or null, but also when it is 0 or empty string, which you may not want so you'd need to specify it in the condition.
Specifically in your case, it would be good not to perform the calculations when either of its parts is not defined as the result will only create undefined or NaN values anyway:
function calculateTotal(){
//first check all you need for the calculation is defined
if (typeof TaxPrice() != 'undefined' && typeof PlanPrice() != 'undefined'){
//perform the calculation and output the result
}else{
//output an error message or a default ouput
}
}
Then you don't have to check for NaN's because those were caused by making arithmetics with undefined's.
Please covert value to a finite number, for example:
function toNumber(value) {
if(typeof value !== 'number') {
// covert type to number
// void 0, null, true, false, 'abc', [], {} => NaN
// [0] => 0
value = parseFloat(value)
}
if(isNaN(value)) {
// check NaN
value = 0
}
if(!isFinite(value)) {
// check Infinity and -Infinity
value = Number.MAX_SAFE_INTEGER * Math.sign(value)
}
return value
}
make a function similar to this
function get_value(input, default_value) {
return input === undefined || isNaN(input) ? default_value : input;
}
and then use it whenever you need to do calculations with a possible undefined value. Eg
var a = 10;
var sum = a + get_value(b, 0); // b is undefined and get_Value returns 0, sum is 10
var prod = a * get_value(b, 1); // b is undefined and get_Value returns 1, prod is 10
Use the isNaN() function to check if a variable is NaN.
e.g. see here: http://www.w3schools.com/jsref/jsref_isnan.asp
You could also track which vars were set in additional vars. ;)
If you want calculation to be done only when both of them are selected, then simply check for these errors in front of your code by:
if(typeof (your_price_variable) !== undefined && typeof (your_country_variable) !== undefined)
and make the function only run when this condition is met. Then the output won't be "NaN."

How to generate a random number only once, and reuse its output?

I'm learning programming starting with Javascript, and my instructor had us doing a random dice roll, a simple Math.ceil(6*Math.random())
I was trying to slightly gameify it and judge the result. So, if you roll a 7, you win, any other roll you lose. The ultimate result would be,
"You rolled a: 7
You win!"
However, I attempt to accomplish by saying approximately:
console.log("You rolled a: " + diceSum);
if (dicesum() == 7) {
console.log("You win!");
} else {
console.log("Aw... you lose. Better luck next time");
}
diceSum() function evaluates each time, so I may get "You rolled a: 7" and "Aw... you lose" because the first roll was a 7, but by the time the if statement came in, the diceSum was something different.
How do I generate a random number like a dice roll and then reuse its value over and over?
Here's my current code (there is far more than necessary because I'm trying to display the values so I know if it is returning the correct answer):
//Functions
//Generate a random single roll of a dice
var getDieRoll = function() {
return Math.ceil(6*Math.random());
};
//Sum up two dice rolls
var diceSum = function() {
var firstDie = getDieRoll();
var secondDie = getDieRoll();
return firstDie+secondDie;
};
//
//Variables
//Check to see if total sum of the roll is 7
var winMsg = "Winner!"
var loseMsg = "Aw... you lose. Better luck next time."
//
//Outputs
//show total sum to compare with message below
console.log(diceSum())
//Return a message stating the result
console.log("You rolled a " + diceSum())
//View true false status to compare with message returned below
console.log(diceSum()==7)
//If diceSum is a 7, give winning message, otherwise give losing message
if (diceSum()==7){
console.log(winMsg);
} else {
console.log(loseMsg);
}
You put the result in a variable, and use the variable:
var sum = diceSum();
//Outputs
//show total sum to compare with message below
console.log(sum);
//Return a message stating the result
console.log("You rolled a " + sum)
//View true false status to compare with message returned below
console.log(sum == 7);
//If diceSum is a 7, give winning message, otherwise give losing message
if (sum == 7){
console.log(winMsg);
} else {
console.log(loseMsg);
}
By the way, the way to calculate the random number is wrong. The random method is defined to return a value that is 0 <= n < 1, i.e. it can be zero, but it can never be one.
If you use Math.ceil, the effect is that the result will occasionally be zero, and the chance to get a six is slightly smaller than the other numbers.
Use Math.floor instead:
function getDieRoll() {
return Math.floor(6 * Math.random()) + 1;
};
Save it to a variable:
var sum = diceSum();
console.log("You rolled a " + sum);
if (sum == 7) {
console.log(winMsg);
} else {
console.log(loseMsg);
}
Or:
var sum = diceSum(),
msg = sum == 7 ? winMsg : loseMsg;
console.log("You rolled a " + sum);
console.log(msg);

How do I round the sum of two function returns that are stored within a variable?

I am using a function calculateTotal() for a form. Within this function is a variable that stores the sum of two other function returns. Depending on user input in the form, the sum can contain several decimal points. i.e. 76.6666666666. I would like to know if I can round this sum before it is displayed? I have tried Math.round(theWholeThing), doesn't work.
I don't know how I would round the number because it can change with user input to the form.
Same with parseint.
function calculateTotal()
{
var theWholeThing = areaTimesType() + getSetUp();
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Total Price For grow space $"+theWholeThing + "\u00A0 \u00A0per month";
}
Try toFixed
(76.6666666666).toFixed(); => 77
(76.6666666666).toFixed(1); => 76.7
Your code will look like this
function calculateTotal()
{
var theWholeThing = areaTimesType() + getSetUp();
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Total Price For grow space $"+(theWholeThing).toFixed(2) + "\u00A0 \u00A0per month";
}
Where are you running Math.round()? Maybe you're not catching the result of the round() function. Try something like:
divobj.innerHTML = "Total Price For grow space $"+ Math.round(theWholeThing) + "\u00A0 \u00A0per month";
Better yet, round the results when you declare theWholeThing:
var theWholeThing = Math.round(areaTimesType() + getSetUp());
Just try this one :
For 2 digit = Math.round(num * 100) / 100
For 3 digit = Math.round(num* 1000)/1000
Detail for this function you can check in
About Math.round

Categories