Create localstorage counter depending on variable (no switch function) - javascript

im just started to learn JavaScript and i´m trying to simplify some code, but couldn´t get a working solution. The working part is this:
switch (v) {
case 0:
if (localStorage.FGAz0) {
localStorage.FGAz0 = Number(localStorage.FGAz0)+1;
} else {
localStorage.FGAz0 = 1;
}
document.getElementById("Ergebnis").innerHTML = "You have " + localStorage.FGAz0+ " Visitor(s).";
break;
case 1:
if (localStorage.FGAz1) {
localStorage.FGAz1 = Number(localStorage.FGAz1)+1;
} else {
localStorage.FGAz1 = 1;
}
document.getElementById("Ergebnis").innerHTML = "You have " + localStorage.FGAz1+ " Visitor(s).";
break;
case 2:
if (localStorage.FGAz2) {
localStorage.FGAz2 = Number(localStorage.FGAz2)+1;
} else {
localStorage.FGAz2 = 1;
}
document.getElementById("Ergebnis").innerHTML = "You have " + localStorage.FGAz2+ " Visitor(s).";
break;
case 3:
if (localStorage.FGAz3) {
localStorage.FGAz3 = Number(localStorage.FGAz3)+1;
} else {
localStorage.FGAz3 = 1;
}
document.getElementById("Ergebnis").innerHTML = "You have " + localStorage.FGAz3+ " Visitor(s).";
break;
case 4:
if (localStorage.FGAz4) {
localStorage.FGAz4 = Number(localStorage.FGAz4)+1;
} else {
localStorage.FGAz4 = 1;
}
document.getElementById("Ergebnis").innerHTML = "You have " + localStorage.FGAz4+ " Visitor(s).";
break;
case 5:
if (localStorage.FGAz5) {
localStorage.FGAz5 = Number(localStorage.FGAz5)+1;
} else {
localStorage.FGAz5 = 1;
}
document.getElementById("Ergebnis").innerHTML = "You have " + localStorage.FGAz5+ " Visitor(s).";
break;
default:
if (localStorage.FahrGastAnzahl) {
localStorage.FahrGastAnzahl = Number(localStorage.FahrGastAnzahl)+1;
} else {
localStorage.FahrGastAnzahl= 1;
}
document.getElementById("Ergebnis").innerHTML = "You have " + localStorage.FahrGastAnzahl+ " Visitor(s).";}
} else {
document.getElementById("Ergebnis").innerHTML = "Sorry, dein Browser unterstützt die Speicherung von lokalen Daten nicht...";
}
and i am trying to short it to the var depending on "v" which only had numbers. At the moment i have this:
if (localStorage.FGAz + "v") {
(localStorage.FGAz + "v") = Number(localStorage.FGAz + "v")+1;
} else {
(localStorage.FGAz + "v") = 1;
document.getElementById("Ergebnis").innerHTML = "You have " + (localStorage.FGAz + "v") + " Visitor(s).";}
Something isn´t right with the adding of the variable "v", but i don´t know what and didn´t found a solution on searching. Hope someone can help me. Please no jquery, i haven´t learned that yet.

Firs of all, make sure you understand the difference between v and "v":
v is a variable name, which can hold any value (string, number, etc), eg:v = 1; v = "1"; v = "xxx";
"v" (mind the brackets) is a string value itself (v = "v", where v is the variable name and "v" is the variable value). Everything inside the brackets (" or ') is a string.
If you wish to cast numerical (integer in this example) value to string, you can use v.toString() or simply append an empty string to the value v + "".
Secondly, please get some knowledge on Property Accessors.
In short: you can access properties of an object in two different ways: using dot notation (localStorage.FGAz1) or brackets notation (localStorage["FGAz1"]).
Appending string value to dot notated property accessor (document.getElementBy + "Id") will firstly evaluate the value of property (document.getElementBy - which evaluates to undefined) and THEN will concatenate it with the string (undefined + "Id" - which results in "undefinedId"). On the other hand, appending string to accessor value inside bracket notation (document["getElementBy" + "Id"]) will firstly evaluate the value of accessor ("getElementBy" + "Id" - which evaluates to "getElementById"), and then access the object's property (document["getElementById"] - which returns the function).
Based on your example:
localStorage.FGAz is not defined, so the localStorage.FGAz + "v" evaluates to undefined + "v" which results in "undefinedv" (Notice the 'v' added to the end of 'undefined'). Sentence if ("undefinedv") always evaluates to true (HERE you can find out why).
In conclusion:
Use brackets notation:
if (localStorage['FGAz' + v.toString()]) {. This will evaluate to if (localStorage['FGAz1']) { for v = 1, if (localStorage['FGAzXXX']) { for v = XXX and so on.
I'm hoping it makes sens to you, if not leave me a question in comments.

I'm looking at the code above and it looks like you're doing some sort of visitor counter. However the localstorage would only work for the one person.
If you're going to be doing vistor counter, you could use ajax to send the information to a database and then check how many people are online.
Simple visit counter:
JSFIDDLE LINK
Code from JSFIDDLE
<div id="visitCount"></div>
if (localStorage.visitCount){
localStorage.visitCount = Number(localStorage.visitCount)+1;
} else {
localStorage.visitCount = 1;
}
document.getElementById("visitCount").innerHTML = "You've been to this page "+ localStorage.visitCount + " time(s)."

Instead of using
localStorage.FGAz + "v"
Use
localStorage["FGAz" + v]
v in "" quotations makes it a string value not variable.

Related

return value 0 instead of undefined

for (var i = 0; i < memberGroup.length; i++) {
subMemberType.push(memberGroup[i]["membershipType"])
}
var subMemTypeCount = [];
while (true) {
subMemberType.forEach(element => {
subMemTypeCount[element] = (subMemTypeCount[element] || 0) + 1;
});
console.log("\t\truby: " + subMemTypeCount["Ruby"]);
console.log("\t\tgold: " + subMemTypeCount["Gold"]);
console.log("\t\tplatinum: " + subMemTypeCount["Platinum"]);
console.log("\t\tdiamond: " + subMemTypeCount["Diamond"]);
break;
}
Output:
ruby: 2
gold: 2
platinum: undefined
diamond: 1
What I am trying to achieve is to print out each membership type "ruby", "gold", "platinum", & "diamond".
I used a forEach to loop through the array subMemberType to count the number of duplicated membership type.
memberGroup[i]["membershipType"] is an 2D array, with a constructor membershipType.
My problem is that when I pushed memberGroup[i]["membershipType"] to array subMemberType, there wasn't the "platinum" membership type. Hence, when I loop through the array using for each to find the duplicated membership type, it returns as undefined. However, I would like it to return "0" instead of "undefined". Is there anyway I can do that?
Instead of setting subMemTypeCount to an empty array (which should have been an object), set it to an object containing those for properties with the value 0. Then you can also reduce the body of the .forEach() to subMemTypeCount[element]++.
As an aside: a while-loop that loops unconditionally and breaks unconditionally after the first iteration, is fully redundant.
const subMemberType = ['Ruby', 'Diamond', 'Ruby', 'Gold', 'Gold'];
var subMemTypeCount = {'Ruby': 0, 'Gold': 0, 'Platinum': 0, 'Diamond': 0};
subMemberType.forEach(element => {
subMemTypeCount[element]++;
});
console.log("\t\truby: " + subMemTypeCount["Ruby"]);
console.log("\t\tgold: " + subMemTypeCount["Gold"]);
console.log("\t\tplatinum: " + subMemTypeCount["Platinum"]);
console.log("\t\tdiamond: " + subMemTypeCount["Diamond"]);
Alternatively you can use the Nullish coalescing operator (??), or the Logical OR (||) in case the nullish coalescing operator isn't supported.
const subMemberType = ['Ruby', 'Diamond', 'Ruby', 'Gold', 'Gold'];
var subMemTypeCount = {};
subMemberType.forEach(element => {
subMemTypeCount[element] = (subMemTypeCount[element] || 0) + 1;
});
console.log("\t\truby: " + (subMemTypeCount["Ruby"] ?? 0));
console.log("\t\tgold: " + (subMemTypeCount["Gold"] ?? 0));
console.log("\t\tplatinum: " + (subMemTypeCount["Platinum"] ?? 0));
console.log("\t\tdiamond: " + (subMemTypeCount["Diamond"] ?? 0));
If you want to handle undefined elements in one line, you can try something like:
console.log ("\t\tplatinum: " + (subMemTypeCount["Platinum"])?subMemTypeCount["Platinum"]:0);
This is basically checking if it is defined or not, If defined -> prints, else 0

Javascript switch(true) executes false statements?

Im looping over a collection of coordinate values and doing math on the coordinates to see if the calculated values are in a hashmap. if they are in the hash map then I want to run an additional function. since I had multiple cases I wanted to check for each coord in the collection, I figured a switch statement would be cool to use to replace my if statements so all my checks could be visually and logically grouped. When I replaced my if statements with a switch, my code returned bad results. When I debugged, I realized the switch statements would sometimes execute even when the case was false(I added console.logs to output the result of the same switch condition and it would print false, but should only run when true). Here is a small example:
var idm = {0:1, 3:1, 9:1, 10:1, 11:1, 12:1, 20:1, 21:1, 23:1}
var findNeighbors = function(b) {
var u,d,l,r,lRow,rRow;
var currentBuilding = parseInt(b);
var currRow = Math.floor(currentBuilding/column);
//remove value from map so we dont recount it.
delete idm[currentBuilding];
u = currentBuilding - column;
d = currentBuilding + column;
l = currentBuilding - 1;
lRow = Math.floor(l/column);
r = currentBuilding + 1;
rRow = Math.floor(r/column);
console.log("current idx:" + currentBuilding);
console.log("u:" + u + ", d:" + d + ", l:" + l + " r:" + r);
// debugger;
switch(true) {
case (idm.hasOwnProperty(u) === true):
console.log((idm.hasOwnProperty(u)));
console.log("map has " + currentBuilding + " -> u: " + u);
findNeighbors(u);
case (idm.hasOwnProperty(d) === true):
console.log((idm.hasOwnProperty(d)));
console.log("map has " + currentBuilding + " -> d: " + d);
findNeighbors(d);
case (lRow === currRow && idm.hasOwnProperty(l) === true):
console.log((lRow === currRow && idm.hasOwnProperty(l)));
console.log("map has " + currentBuilding + " -> l: " + l);
findNeighbors(l);
case (rRow === currRow && idm.hasOwnProperty(r) === true):
console.log((rRow === currRow && idm.hasOwnProperty(r)))
console.log("map has " + currentBuilding + " -> r: " + u);
findNeighbors(r);
}
console.log("---------------------------");
}
I figured a switch statement would be cool to use to replace my if statements so all my checks could be visually and logically grouped.
Well, write code that works not code that looks cool. You were forgetting break statements, so the execution flow fell through - without evaluating the other case expressions after the first one matched. Btw switching on a constant is a horrible (uncool) practice.
Use standard if/else instead.

How can I replace certain data strings with predefined data using Javascript?

I would like to use JavaScript to take data entered into a text field and replace the first two digits with a character and at the same time preserve the remaining digits in the string. The input data will always be 6 digits in length and there are 4 different possible character options depending on the first 2 digits of the input data. Here are the four possible options.
00 = A, 01 = M, 31 = B, 71 = F
So for example, if the input data is 001234, the output would need to be A1234. If the input is 719999, the output needs to be F9999.
I appreciate any help you can provide and thank you in advance for your support.
You declare tc_event; I assume this is a value returned by another function or application. But in your function you call TC_event. Please bare in mind that variables in JS are case sensitive. So tc_event is an entirely different variable than TC_event.
In your function you don't assing the returned value of strNewFld to tc_event so even while returned, tc_event will remain the initial value.
var persNr = "711212";
var strSrc = persNr ;
var strLtr = strSrc.substring(0,2);
var strNum = strSrc.substr(2,4);
console.log("This is strLtr: " + strLtr);
console.log("This is strNum: " + strNum);
var strNewFld = "";
var strLtrOut= "";
// In your if statement you use a single =. This means assign.
// To compare allways use ==. This compares.
if (strLtr == "00"){
strLtrOut = "A";
}
if (strLtr == "01"){
strLtrOut = "M";
}
if (strLtr == "31"){
strLtrOut = "B";
}
if (strLtr == "71"){
strLtrOut = "F";
}
strNewFld = strLtrOut + strNum;
// here you could assign value of strNewFld
// to tc_event or directly assiging
// strLtrOut + strNum to tc_event.
tc_event = strLtrOut + strNum
console.log("This is strNewFld: " + strNewFld);
I put it in a Snippet for you to understand what your variables do and how to manipulate it with if statements. A Switch statement should be more suitable. You can ask if needed.
var persNr = "021212"
var strLtr = persNr.substring(0,2);
var strNum = persNr.substr(2,4);
if (strLtr == "01"){
strLtrOut = "A" + strNum ;
}
if (strLtr == "02"){
strLtrOut = "B" + strNum ;
}
console.log("This is strLtr: " + strLtr);
console.log("This is strNum: " + strNum);
console.log("This is strLtrOut: " + strLtrOut);

javascript how to make an operator from string

Is it possible to make an operator type of string into operator
<script>
var operator = $(this).val(); returns a string eg) + or -
var quantity = 5 operator 1;
</script>
currently i am using switch
It's possible, in a way, via eval, but see caveats. Example:
var result = eval("5 " + operator + " 1"); // 6 if operator is +
The problem with eval is that it's a full JavaScript evaluator, and so you have to be really sure that the content is under your control. User-contributed content, for instance, is something you have to be very, very cautious with.
Alternately, just do a switch:
switch (operator) {
case "+":
result = 5 + 1;
break;
case "-":
result = 5 - 1;
break;
case "/":
result = 5 / 1;
break;
case "*":
result = 5 * 1;
break;
// ...and so on, for your supported operators
}
The absolutely most simple way would be to use a if:
var operator = $(this).val(); // returns a string eg) + or -
var quantity;
if(operator === '-') {
quantity = 5 - 1;
} else if(operator === '+') {
quantity = 5 + 1;
}
You could also use the eval function, but eval is very rarely recommended and is not really worth it in a case like this.
No. The easiest would be to use eval:
var quantity = eval("5 " + operator + " 1");
but it is considered a bad practice. Eval is Evil. Not only do you have security concerns, it also slows down the execution of your code.
Rather, this approach is much better and safer:
var operators = {
"+": function(a, b) { return a + b; };
"-": function(a, b) { return a - b; };
};
var operatorFunction = operators[operator];
if (operatorFunction) {
var quantity = operatorFunction(5, 1);
}

How do you write an arithmetic expression parser in JavaScript, without using eval or a constructor function?

Given a string:
var str1 = "25*5+5*7";
Without using eval or the constructor function in JavaScript, how would I be able to write a function called "output" that takes in the string and outputs the arithmetic value of the string, which in this case is 160?
Here's a full precedence expression evaluator following the recursive parsing
idea I linked-to in a comment on the OP's question.
To do this, first I wrote a simple BNF grammar for the expressions I wanted to process:
sum = product | sum "+" product | sum "-" product ;
product = term | product "*" term | product "/" term ;
term = "-" term | "(" sum ")" | number ;
This by itself requires a bit of experience to do simply and straightforwardly. If you have no experience with BNF you will find
it incredibly useful for describing complex streams of items like expressions, messages, programming langauges, ...
Using that grammar, I followed the procedure outlined in the other message
to produce the following code. It should be obvious that it is driven by grammar in a dumb mechanical way, and therefore pretty easy to write if you have that grammar.
(Untested. I'm not a JavaScript coder. This will surely contain a few syntax/semantic hiccups. Took me at about 15 minutes to code.)
var SE="Syntax Error";
function parse(str) { // returns integer expression result or SE
var text=str;
var scan=1;
return parse_sum();
function parse_sum() {
var number, number2;
if (number=parse_product()==SE) return SE;
while (true) {
skip_blanks();
if (match("+") {
number2=parse_product();
if (number2==SE) return SE;
number+=number2;
}
else if (match('-')) {
{ number2=parse_product();
if (number2==SE) return SE;
number-=number2;
}
else return number;
}
}
function parse_product() {
var number, number2;
if (number=parse_number()==SE) return SE;
while (true) {
if (match("*") {
number2=parse_term();
if (number2==SE) return SE;
number*=number2;
}
else if (match('/')) {
number2=parse_term();
if (number2==SE) return SE;
number/=number2;
}
else return number;
}
}
function parse_term() {
var number;
skip_blanks();
if (match("(")) {
number=parse_sum();
if (number=SE) return SE;
skip_blanks();
if (!match(")") return SE;
}
else if match("-") {
number= - parse_term();
}
else if (number=parse_number()==SE) return SE;
return number;
}
function skip_blanks() {
while (match(" ")) { };
return;
}
function parse_number() {
number=0;
if (is_digit()) {
while (is_digit()) {}
return number;
}
else return SE;
}
var number;
function is_digit() { // following 2 lines are likely wrong in detail but not intent
if (text[scan]>="0" && text[scan]<="9") {
number=number*10+text[scan].toInt();
return true;
}
else return false;
}
function match(c) {
if (text[scan]==c)
{ scan++; return true }
else return false;
}
}
It is straightforward to code such parsers/evaluators. See my SO answer on how to build a parser (which links to how to how to build an evaluator).
This is a simple parser with * over + precedence. I've tried to make it as educational as possible. I'll leave it up to you to add division and subtraction. Or brackets, if you're particularly ambitious.
function parse(str) {
var signs = ["*", "+"]; // signs in the order in which they should be evaluated
var funcs = [multiply, add]; // the functions associated with the signs
var tokens = str.split(/\b/); // split the string into "tokens" (numbers or signs)
for (var round = 0; round < signs.length; round++) { // do this for every sign
document.write("tokens at this point: " + tokens.join(" ") + "<BR>");
for (var place = 0; place < tokens.length; place++) { // do this for every token
if (tokens[place] == signs[round]) { // a sign is found
var a = parseInt(tokens[place - 1]); // convert previous token to number
var b = parseInt(tokens[place + 1]); // convert next token to number
var result = funcs[round](a, b); // call the appropriate function
document.write("calculating: " + a + signs[round] + b + "=" + result + "<BR>");
tokens[place - 1] = result.toString(); // store the result as a string
tokens.splice(place--, 2); // delete obsolete tokens and back up one place
}
}
}
return tokens[0]; // at the end tokens[] has only one item: the result
function multiply(x, y) { // the functions which actually do the math
return x * y;
}
function add(x, y) { // the functions which actually do the math
return x + y;
}
}
var str = "25*5+5*7";
document.write("result: " + str + " = " + parse(str));
You can use the expression parser of math.js:
var str1= "25*5+5*7"
document.write(str1 + ' = ' + math.eval(str1));
// output: "25*5+5*7 = 160"
<script src="http://cdnjs.cloudflare.com/ajax/libs/mathjs/2.1.1/math.min.js"></script>
You can create a new script:
function parse(str) {
var s = document.createElement('script');
s.text = "window.result = " + str;
document.body.appendChild(s); // Run script
document.body.removeChild(s); // Clean up
return result; // Return the result
}
document.body.innerHTML = parse("5*5+5*5");
Or use event handler content attributes:
function parse(str) {
var el = document.createElement('div');
el.setAttribute('onclick', "this.result = " + str);
el.onclick(); // Run script
return el.result; // Return the result
}
document.body.innerHTML = parse("5*5+5*5");
Note these approaches are unsafe and as evil as eval but uglier. So I don't recommend them.

Categories