Javascript Changing a Bound Value - javascript

This function is designed to report and increment the total (counter) for each specific obstacle.
function warningMaker( obstacle ){
var count = 0;
return function ( number, location ) {
count++;
alert("Beware! There have been " +
obstacle +
" sightings in the Cove today!\n" +
number +
" " +
obstacle +
"(s) spotted at the " +
location +
"!\nThis is Alert #" + count + " today for " + obstacle + " danger."
);
};
}
Now if I call the function by saying for example,
warningMaker("obstacleName1")(2,"locationName"); ===counter 1
warningMaker("obstacleName1")(2,"locationName"); ===counter still 1
But if I call it this way,
var obstacle1Maker = warningMaker("obstacleName1");
var obstacle2Maker = warningMaker("obstacleName2");
obstacle1Maker(2,"MiddleEarth");
obstacle1Maker(2,"Hogwarts");
obstacle2Maker(3,"Narnia");
The counter is incremented for every specific obstacle, how is this possible? I'm new to Javascript and I'm trying to grasp the concepts behind things like this.

Two different closures hold two different counters. You want sth like this:
var obstacles={};
function warningMaker( obstacle ){
var obstacles[obstacle] = obstacles[obstacle]||0;
return function ( number, location ) {
obstacles[obstacle]++;
alert("Beware! There have been " +
obstacle +
" sightings in the Cove today!\n" +
number +
" " +
obstacle +
"(s) spotted at the " +
location +
"!\nThis is Alert #" + obstacles[obstacle] + " today for " + obstacle + " danger."
);
};
}
Im storing all counts in a global object. Its therefore not dependent on closures etc...
Why your code doesnt work as expected:
warningMaker("obstacleName1");
This assembles a new function context ( function + closure ). It happens when you move a function out of its scope ( variable surrounding ). The function can still access it, as its bound to them ( called closure). So if you call that twice, you will create two different contexts with two different count variables...

Related

Trying to populate string with values from object properties - getting "undefined"

I am trying to solve the below Javascript kata on Codewars but getting "undefined". Can please someone show me the light on what exactly is "undefined". I am struggling to understand what is missing form my code below. Cheers.
Link to challange: https://www.codewars.com/kata/training-js-number-5-basic-data-types-object
I've searched through FreeCodeCamp JS OOP and Basic tutorials / lessons to find similar problems. Searched through StackOverflow, Reddit, and Googled many websites for similar challanges.
Code below:
function animal(name, legs, color) {
this.name = name;
this.legs = legs;
this.color = color;
}
var dog = new animal("dog", 4, "white");
// similar variables set such for other animal objects.
animal.prototype.toString = function animalToString() {
var sent = "This " + this.color + " " + this.name + " has " + this.legs + " legs.";
return sent;
}
return animal.prototype.toString.call();
Expected: This white dog has 4 legs., instead got: undefined
Try this:
function animal(obj){
var newAnimal = {
name: obj.name,
legs: obj.legs,
color: obj.color
};
return "This " + newAnimal.color + " " + newAnimal.name + " has " + newAnimal.legs + " legs.";
}
The purpose of this kata I believe is to introduce you to javascript objects. The issue is thrown when you changed the inputs of the function "animal". If you look at the sample tests in the lower right corner, the inputs being fed into the function you are trying to make should accept only one parameter which is an object with properties name, legs, and color. You changed this input into three separate parameters instead of just one.
Or you could skip the assignment altogether and just access the input directly like so:
function animal(obj){
return "This " + obj.color + " " + obj.name + " has " + obj.legs + " legs.";
}
1) Based on 'instructions'
Give you a function animal, accept 1 parameter obj like this: {name:"dog",legs:4,color:"white"} and return a string like this: "This white dog has 4 legs."
function animal({name, legs, color}) {
return `The ${color} ${name} has ${legs} legs.`;
}
2) Based on what you're supposed to learn
function animal({name, legs, color}) {
this.name = name;
this.legs = legs;
this.color = color;
}
animal.prototype.toString = function animalToString() {
return `The ${this.color} ${this.name} has ${this.legs} legs.`;
}
var dog = new animal({name:"dog", legs:4, color:"white"});
dog.toString();
function animal(obj){
return `This ${obj.color} ${obj.name} has ${obj.legs} legs.`
}
You can try this
function animal(obj){
var a={name:"dog",legs:4,color:"white"}
return "This" + " " + a.color + " " +a.name + " " + "has" + " " + a.legs + " " + "legs.";
}

Trying to get this string to appear in a paragraph

Trying to get this string I have in JavaScript to appear in a paragraph in my HTML page by mousing over another paragraph.
function showInfo()
{
for (i = 0; i < object2; i = i + 1)
{
var myParagraph = "Name of Business: " + info.insurance[i].name + "\nState: " + info.insurance[i].state + "\nDiscount: " + info.insurance[i].discount + "\n" + "(" + i + 1 + "of" + object2 + ")"
}
}
myDiscount.addEventListener("mouseover", showInfo, false);
myDiscount.addEventListener("mouseout", showInfo, false);
<p id="discount">Show me the discounts!</p>
<p id="myP"></p>
If you want to show the next element of the info.insurance array each time you mouse over the paragraph, you shouldn't be using a for loop. That will do it all at once, not once for each mouseover. You need to put the counter in a global variable, and just increment it each time you call the function.
Yuo show it by assigning it to the innerHTML of the paragraph. You also need to use <br> rather than \n to make newlines (unless the style of the paragraph is pre).
var insurance_counter = 0;
function showInfo() {
var myParagraph = "Name of Business: " + info.insurance[insurance_counter].name + "<br>State: " + info.insurance[insurance_counter].state + "<br>Discount: " + info.insurance[insurance_counter].discount + "<br>(" + (insurance_counter + 1) + "of" + object2 + ")";
document.getElementById("myP").innerHTML = myParagraph;
insurance_counter++;
if (insurance_counter >= object2) { // wrap around when limit reached
insurance_counter = 0;
}
}

Vue.js mounted function runs too early

Essentially what I am trying to do is to run a a function that adds up different variables and sets a new one its pretty simple:
addup: function () {
this.homeScore1 = this.m1g1h + this.m1g2h + this.m1g3h + this.m1g4h + this.m2g1h + this.m2g2h + this.m2g3h + this.m2g4h;
this.awayScore1 = this.m1g1a + this.m1g2a + this.m1g3a + this.m1g4a + this.m2g1a + this.m2g2a + this.m2g3a + this.m2g4a;
this.homeScore2 = this.m3g1h + this.m3g2h + this.m3g3h + this.m3g4h + this.m4g1h + this.m4g2h + this.m4g3h + this.m4g4h;
this.awayScore2 = this.m3g1a + this.m3g2a + this.m3g3a + this.m3g4a + this.m4g1a + this.m4g2a + this.m4g3a + this.m4g4a;
this.hdoubles = this.m5g1h + this.m5g2h + this.m5g3h + this.m5g4h;
this.adoubles = this.m5g1a + this.m5g2a + this.m5g3a + this.m5g4a;
alert(this.m1g1h);
//total handicap is set here
this.hhandicap = this.singlesHHandicap + this.doublesHHandicap;
this.ahandicap = this.singlesAHandicap + this.doublesAHandicap;
//total score is calculated here
this.homescore = this.homeScore1 + this.homeScore2 + this.hdoubles + this.hhandicap;
this.awayscore = this.awayScore1 + this.awayScore2 + this.adoubles +this.ahandicap;
},
the value of this.m1g1h for example is set in a function called this.updatesSinglesScores(); that is run on page creation, It calls my databse and assignes the values returned to some vue variables:
created: function () {
this.updatesSinglesScores();
this.updateDoublesScores();
},
afterwards I call the addup function on mounted:
mounted: function () {
this.addup();
}
So the problem I am having is that the variable this.homeScore1 for example, that is being displayed in the html of the page does not chnages it remains to 0. Upon further inspection with the alert in the addup function I learned that this.m1g1h remains 0, even though it should be another value. Furthermore if I run the addup function with a button everything works fine. So could some one explain to me why this.m1g1h remains 0? also why does the addup function work when called from a button?

is there a way to get info from a variable that is defined inside a function?

I am trying to figure out if there is a way to access the information stored inside a variable that I defined inside a function? I am kinda confused on how to do what I am trying to do here...
note: this isn't the full code, but the piece of the code I need help with.
let question1 = new Question("What is California State Flower?", "1. Rose. 2. Tulip. 3. Poppy");
firstQuestion();
function firstQuestion(){
let someAnswer = prompt(question1.questionName + " " + question1.questionString);
}
if (someAnswer == "poppy"){
I am trying to use the if statement to figure out if a question answer is correct, but I can't do that because someAnswer was defined inside the function.... and i'm not sure if there is a way to do this without using a function?
Update:
Ok, I got that piece working, but now my code's if/else statement isn't working. if i put in the wrong answer, it says I have the right answer. I don't really see any logical reason for that...
//store score total
let pointsCount = 0;
//questions
class Question {
questionName: string;
questionString: string;
constructor(questionName:string, questionString:string){
this.questionName = questionName;
this.questionString = questionString;
}
}
//question one
let question1 = new Question("What is the California State Flower?", "1. Rose. 2. Tulip. 3. Poppy.");
let firstAnswer = firstQuestion();
function firstQuestion(){
return prompt(question1.questionName + " " + question1.questionString);
}
if (firstAnswer === "Poppy" || "poppy"){
pointsCount ++;
alert("You got it!" + " " + "You now have" + " " + pointsCount + " " + "points!");
} else {
alert("Wrong!" + " " + "You now have" + " " + pointsCount + " " + "points!");
}
//question two
let question2 = new Question("What is the California State Bird?","1. Quail. 2. Eagle. 3. Penguin.")
let secondAnswer = secondQuestion();
function secondQuestion(){
return prompt(question2.questionName + " " + question2.questionString);
}
if (secondAnswer === "quail" || "Quail"){
pointsCount++;
alert("You got it!" + " " + "You now have" + " " + pointsCount + " " + "points!");
} else if (secondAnswer !== "quail" || "Quail") {
alert("Wrong!" + " " + "You now have" + " " + pointsCount + " " + "points!");
}
You're close; you're not returning anything from your firstQuestion function, so nothing's ever really going to happen when you run this.
let question1 = new Question("What is California State Flower?", "1. Rose. 2. Tulip. 3. Poppy");
let answer = firstQuestion();
function firstQuestion(){
// return whatever the user enters in the prompt
return prompt(question1.questionName + " " + question1.questionString);
}
if (answer.toLowerCase() == "poppy"){
// call .toLowerCase on your answer to ensure you've covered capitalization edge-cases
}
Maybe this is what you need
let someAnswer;
function firstQuestion(){
someAnswer = prompt(question1.questionName + " " + question1.questionString);
}

Arithmetic with variables not working

For some reason, the arithmetic in the function updateScore(result) doesn't work properly (the function is called later on in the code). wins, ties and losses are printed as they should, but lives is printed as NaN. I know what NaN means. I've also identified that the variables, for some reason or other, are created as strings. What appears strange to me, is that it's working for four out of five variables. There's no consistency. I've tried some number conversions using Number(lives), but that doesn't work either. Any suggestions to how I can ensure that the variables are created as numbers, and aritmethic operations will work?
var wins = 0,
ties = 0,
losses = 0,
lives = 5,
previouscpuChoice = 0;
$("#startknapp").click(function(){
var spiller = prompt("Hva heter du?");
$("#userSelect").html(userMenu);
$("#result").html("<h4>Velg figur, " + spiller + "</h4>");
$("#status").html('<h4>Liv: <span id="life">' +lives+ '</span> - Seire: <span id="win">' + wins + '</span> - Uavgjort: <span id="tie">' + ties + '</span> - Tap: <span id="lose">' + losses + '</span>');
console.log(typeof "lives");
console.log(typeof "wins");
});
function updateScore(result) {
tie = document.getElementById("tie");
win = document.getElementById("win");
lose = document.getElementById("lose");
lives = document.getElementById("life");
console.log(typeof "wins");
var imgSrc = "images/" + userChoice + "-" + result + ".png";
if (result === "tie") {
ties = ties + 1;
tie.innerHTML = ties;
$('.result-img').attr('src', 'images/tie.png');
}
if (result === "vant") {
wins++;
$('.result-img').attr('src', imgSrc);
}
if (result === "tapte") {
losses++;
lives--;
lose.innerHTML = losses;
life.innerHTML = lives;
$('.result-img').attr('src', imgSrc);
}
};
Have you tried the following?
var tie = parseInt(document.getElementById("tie").value);
Your current code:
document.getElementById("tie")
retrieves the DOM element rather than the value of the input. so you need to use .value and then you parse it as an integer as the inputs value is likely a string representation of the number you want rather than an integer value.
After pondering, I figured it's okay if the variables are strings, and looked at the code from a different perspective. And what do you know, it was a simple bug.
$("#startknapp").click(function(){
var spiller = prompt("Hva heter du?");
$("#userSelect").html(userMenu);
$("#result").html("<h4>Velg figur, " + spiller + "</h4>");
$("#status").html('<h4>Liv: <span id="life">' +lives+ '</span> - Seire: <span id="win">' + wins + '</span> - Uavgjort: <span id="tie">' + ties + '</span> - Tap: <span id="lose">' + losses + '</span>');
console.log(typeof "lives");
console.log(typeof "wins");
});
function updateScore(result) {
tie = document.getElementById("tie");
win = document.getElementById("win");
lose = document.getElementById("lose");
life = document.getElementById("life");
Originally the last line of updateScore(result) was:
lives = document.getElementById("life");
As a result two variables were mixed (the local one for the function (life) and the global one (lives). So in the end it was a typo. However, I'm still intrigued by the fact that a variable can be a string, and the value contained within an integer.

Categories

Resources