JavaScript function will only work once - javascript

I have a JavaScript function that is triggered onchange. What it does is take the value from a input field and then add it to the value entered in another field and then display the answer in a different field.
It works fine the first time, but when I enter a new value and leave the field there is an error: TotalPurchasePrice is not a function
function TotalPurchasePrice(BuyinPrice, TopupAmount) {
var BuyinPrice
var TopupAmount
BuyinPrice = BuyinPrice.toString().replace(/\£|\,/g, '');
TopupAmount = TopupAmount.toString().replace(/\£|\,/g, '');
TotalPurchasePrice = (BuyinPrice * 1) + (TopupAmount * 1);
document.getElementById('tTotalPurchasePrice').value = TotalPurchasePrice;
}
Can anyone tell me why this would only work once?

This line :
TotalPurchasePrice = (BuyinPrice * 1) + (TopupAmount * 1);
replaces the TotalPurchasePrice function by a number. Then it's not a function, hence the error you have.
Use a different variable name :
var totalPrice = (BuyinPrice * 1) + (TopupAmount * 1);
document.getElementById('tTotalPurchasePrice').value = totalPrice;
You could also simply have added the var keyword but it would have made the code confusing.
A way to reduce the probability of such errors is to follow best practices when naming functions and variables. Here you should have named your function as a verb to denote an action instead of a value.

You're are confusing JavaScript with VBScript here.
To return value use return keyword:
return (BuyinPrice * 1) + (TopupAmount * 1);
Then outside the function have such line:
document.getElementById('tTotalPurchasePrice').value = TotalPurchasePrice(BuyinPrice, TopupAmount);

Assigning the value of a variable inside a function without stating it with var (TotalPurchasePrice in your case) means that the variable is global.
Since you could have the function declaration written as: var TotalPurchasePrice = function(BuyinPrice, TopupAmount) {}, you are just overriding it.
You could either rename the variable inside the function or add a var statement in front of it like:
var TotalPurchasePrice = (BuyinPrice * 1) + (TopupAmount * 1);

Related

how do i create a simple onclick add function()

i try to do these code and expecting it for increase by 1 everytime i click on the button but it returns me NaN instead.
im really new to javascript. really hope someone could help me!
thanks in advance.
function add(){
var sum = parseInt(1);
var adding = adding + sum;
document.getElementById("amt1").innerText = adding;
}
I see, here you've asked two problems:
Why adding is NaN
At line #2, you haven't initialized variable adding, hence in RHS adding is undefined.
Therefore, the RHS block adding + sum; is evaluated as undefined + 1, which evaluates to NaN
How to use onClick()
W3School's tutorial on onClick()
Here is your code in working state (HTML + JavaScript):
var adding = 0; // initialization. This is the step, that your code was missing
function add() {
var sum = parseInt(1);
adding = adding + sum;
document.getElementById("amt1").innerText = adding;
}
<h1>The onclick Event</h1>
<button onclick="add()">Click me</button>
<p id="amt1"></p>
You could take a closure over the sum and take the returned function for adding to the value.
var add = function(sum) {
return function () {
document.getElementById("amt1").innerHTML = ++sum;
};
}(0);
<span id="amt1">0</span> <button onclick="add()">add</button>
You're making the assignment in the local scope of the function, so every time the function executes, it's going to assign the value 1 to the 'sum' variable. Next, you're creating the variable 'adding' by trying to assign the value of adding, which doesn't exist yet.
It seems like the goal of your function is to just increment the value of 'amt1' by one.
function add(elId){
let currentAmt = document.getElementById(elId).innerText;
currentAmt = parseInt(currentAmt) + 1;
document.getElementById(elId).innerText = currentAmt;
}
By passing in the element ID, your function can now be applied to any element. It parses the integer from its current inner text, adds 1, then sets the new amount to the inner text of the element.
you might need to have a look on this post- Increment value each time when you run function
about how to increment, the idea is keep the variable outside the function as in you case,
you dont need parseInt as its used for parsing integers from a string.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
you need to keep the sum variable outside function. following is the general function to add
var n = 0;
function add(value){
n += value;
return n;
}
try it
document.getElementById("amt1").addEventListener("click", displayDate);
function displayDate() {
var node = document.getElementById('amt1');
document.getElementById("amt1").innerHTML = parseInt(node.textContent)+1;
}
<button id="amt1">1</button>
You're using an undefined variable adding to make your calculation that's why you get a NaN as a result :
var adding = adding + sum : the variable adding isn't yet initialized so it's value equals to undefined which give us var adding = undefined + sum = NaN. See next example :
var sum = parseInt(1);
console.log('typeof "adding" before initialization is ' + typeof adding + ' and it equals "' + adding + '"');
var adding = adding + sum;
console.log('typeof "adding" after initialization is ' + typeof adding + ' and it equals "' + adding + '"');
BTW, you don't need parseInt in order to put manually a number, sum = parseInt(1) is the same as sum = 1 but the later is faster.
And now here's how to accomplish your task :
/**
* btn: the button to be clicked to increment the counting.
* counterTxt: the "p#counter" element that prints the counting.
* counter: keeps track of the number of the clicks made.
**/
const btn = document.getElementById('btn'),
counterTxt = document.getElementById('counter');
let counter = 0; /** holds the number of clicks **/
/** click event handler for the "button" **/
btn.addEventListener('click', () => counterTxt.textContent = ++counter); /** update the "p#counter" text and increment the counter **/
<button id="btn">click to increment</button>
<p id="counter">0</p>

How to access the value of a math.random calculation?

I'm writing a program that simulates a card shuffler. The program should randomly selects a random image within an array and displays it to the screen. Then it deletes that image from the array before running again. The problem I'm having is storing the value of the randomized number so I can delete said array position from the array. I'm pretty sure the math.random calculation needs to be within a function, but I'm having a hard time using that value to randomize the array position while simultaneously storing that random value.
var shuffler = {
cards: [...]
displayCard: function() {
document.getElementById("card-1").style.backgroundImage = 'url(' +
shuffler.cards[shuffler.randomizer()] + ')';
},
randomizer: function() {
Math.floor(Math.random() * shuffler.cards.length) = randomized;
return this.randomized;
shuffler.cards.splice(randomized, 1)
}
}
shuffler.displayCard();
You cannot store the value correctly because following line is errorsome
Math.floor(Math.random() * shuffler.cards.length) = randomized;
= sign in programming is not like = in math. It just assigns the value of right side to left side. Thus, you should do it like this instead:
this.randomized = Math.floor(Math.random() * shuffler.cards.length);
There are two problems. First one is with assignment of randomized. See the line
Math.floor(Math.random() * shuffler.cards.length) = randomized;
Here the LeftHandSide of assignment expression is an expression which is wrong. It should be
let randomized = Math.floor(Math.random() * shuffler.cards.length);
The second problem is that you are using splice() after return move it before return
The last problem is that you are using the variable name inside the methods of the object. You should use this instead of shuffler. The final code will look like.
var shuffler = {
cards: [...]
displayCard: function() {
document.getElementById("card-1").style.backgroundImage = 'url(' +
this.cards[this.randomizer()] + ')';
},
randomizer: function() {
let randomized = Math.floor(Math.random() * shuffler.cards.length);
this.cards.splice(randomized, 1)
return randomized;
}
}
shuffler.displayCard();
In the code snippet you have you're returning before you splice from your array, making it dead code that's unreachable.
In terms of answering the title of this question, you're in the right spirits of just simply storying the random number as a variable, however you need to have proper syntax.
bro check your syntax
randomizer: function() {
Math.floor(Math.random() * shuffler.cards.length) = randomized;
return this.randomized;
shuffler.cards.splice(randomized, 1)
}
I think it will be
randomizer: function() {
this.randomized = Math.floor(Math.random() * this.cards.length);
this.displayCard(this.randomized);
shuffler.cards.splice(this.randomized, 1);
return this.randomized;
}
and you also need to declare randomized property in your shuffler object.
You also need to fix your displayCard method.
displayCard: function(index) {
document.getElementById("card-1").style.backgroundImage = 'url(' +
shuffler.cards[index] + ')';
}

Set function result to variable within same function on external javascript file

The following is not bringing the results of my function into a variable and into my html page... why?
EXTERNAL JAVASCRIPT
function damageRoll(min, max) {
'use strict';
document.getElementById("combatResult").innerHTML = damageFinal;
min = min || peacemaker.damageMin;
max = max || peacemaker.damageMax;
var damageFinal = damageRoll();
return Math.floor(Math.random() * (max - min + 1) ) + min;}
HTML
<div id="combatResult"></div>
<button onclick="damageRoll()">Fight</button>
EDIT
Going to read through everyone's answers but min/max probably not the issue. I failed to show they get their values from another external js file and are functioning as expected in other areas of my code. Thanks.
EXTERNAL JAVASCRIPT #2
var peacemaker = {
damageMin: 3,
damageMax: 5,
};
You probably want thing like this.
function damageRoll(min, max) {
'use strict';
min = min || peacemaker.damageMin;
max = max || peacemaker.damageMax;
var damageFinal = Math.floor(Math.random() * (max - min + 1) ) + min;
document.getElementById("combatResult").innerHTML = damageFinal;
}
First, the min and max modification should be put at the front of the function. You should also consider put the damageFinal variable declaration earlier in the function like the above example. Don't overuse JavaScript's variable hoisting feature.
Next, your original code results in a endless self invoking. I don't understand your intention, but it will be better not to use self invoking in your situation.
PS: You can make code even simpler by using es6
function damageRoll(min = peacemaker.damageMin, max = peacemaker.damageMax) {
var damageFinal = Math.floor(Math.random() * (max - min + 1) ) + min;
document.getElementById("combatResult").innerHTML = damageFinal;
}
Your damageRoll() calls do not actually contain the required parameters min and max. You must add items when you're calling it, like here:
<button onclick="damageRoll(min, max)">Fight</button>
and within the function itself:
var damageFinal = damageRoll(min, max);
You're recursively calling the function, without a base. Nothing is going to occur, because the function will never finish being called. You may want to look into this.
it looks like you are a beginner learner so i will explain what i did instead of just posting the right answer.
First of all, you should split your function to one that handle the click event and one the calculate the result. it's better that the second function will use inner cope only (don't use variable from outside the function)
so your code should look like:
// example values for object
const peacemaker = {
damageMin: 100,
damageMax: 100
}
function damageRollEvent(e) {
'use strict';
e.preventDefault();
var _peacemaker = {
min: min || peacemaker.damageMin,
max: max || peacemaker.damageMax
}
var damageFinal = damageRoll(_peacemaker);
document.getElementById("combatResult").innerHTML = damageFinal;
}
function damageRoll(_peacemaker) {
'use strict';
return Math.floor(Math.random() * (_peacemaker.max - _peacemaker.min + 1)) + _peacemaker.min;
}
damageRollEvent function handle the event and messing with the html.
damageRoll returns the value you expect for and doing pure programming work.
the html
<div id="combatResult"></div>
<button onclick="damageRollEvent($event)">Fight</button>
i didn't test the code but it should work.
This is the way you shall proceed without recursively calling the function, you shall add a helper function in the middle. From the HTML you shall call the helper. Anyway you have to find a way to resolve the 2 variablrs, min and max. See this..
function damageRoll(min, max) {
var damageFinal = Math.floor(Math.random() * (max - min + 1) ) + min;
document.getElementById("combatResult").innerHTML = damageFinal;
}
function throwMinMax(){
// You should Find a way to resolve the two variables below
// we have No idea where the peacemaker stuff come from
var min = peacemaker.damageMin;
var max = peacemaker.damageMax;
damageRoll(min,max);
}

Create global variable and generate random number and update the variable when the function is called in Javascript

I am kinda new in this coding environment and trying to challange myself with exercises.
I am trying to create global variable called quoteNumber and generate a random number and update this variable every time when the function is called.
However with the code below, every time I call the function quoteNumber variable stays the same and not updated with new random number.
I can solve this putting all variables inside the function but since I am using those variables in different functions I guess it is better for me to create global variable for it.
What are your suggestions?
var quotes = [{"quote":"Knowledge speaks, but wisdom listens.","author":"Jimi Hendrix"}];
var quoteNumber = 0 ;
var generatedQuote = quotes[quoteNumber].quote;
var generatedAuthor = quotes[quoteNumber].author;
function quoteGenerator () {
quoteNumber = Math.floor(Math.random() * 80) + 1;
document.getElementById("text").innerHTML = generatedQuote;
document.getElementById("author").innerHTML = generatedAuthor;
}
function share() {
document.getElementById("tweet-quote").attr('href', 'https://twitter.com/intent/tweet?hashtags=quotes&text=' + encodeURIComponent('"' + generatedQuote + '" ' + generatedAuthor));
}
PS- I have shortened the quotes variation and put here not to create confusion
When calling the function you are properly updating the quoteNumber-variable. However, both generatedQuote and generatedAuthor are still the value you set from the beginning.
So, after setting the quoteNumber to a new value, you will have to do
generatedQuote = quotes[quoteNumber].quote;
generatedAuthor = quotes[quoteNumber].author;
To update those variables as well.

Variable scope outside of JQuery Event

I keep getting undefined for quarterStr? I am trying to access it in the getNexthreeMonths function. So a month is chosen from a drop down menu and then I want to access the result in the getNexthreeMonths:
getNextThreeMonths: function() {
$("#date").on('change', function (e){
var currentMonth = $(this).find('option:selected').attr('id');
var currentMonth = parseInt(currentMonth);
var qNum = Math.floor(currentMonth / 3);
var qArr = ["Jan","Apr","Jul","Oct"];
var quarterStr = qArr[ (qNum+1) % 4 ] + "," + qArr[ (qNum+2) % 4 ] + "," + qArr[ (qNum+3)%4 ];
});
console.log(quarterStr);
}
There are two reasons for this.
First, the var in var quarterStr = means the variable is locally scoped to the anonymous function you pass as an argument to on() and can't be accessed outside that function.
Second, the value isn't assigned to quarterStr until the change event on the date element fires and that function is run. You're trying to read the value just after you assign the event handler. There is no way that it will have changed by then, so it will always be undefined.
You need to rethink your logic. You can't use JavaScript to time travel and figure out what the user might do at some point in the future.

Categories

Resources