Javascript List clarification - javascript

var list = {};
list[19] = 'kapooya';
list[20] = 'apples';
delete list[19];
Does
list[19] == 'apples' or null?

var list = {};
list[19] = 'kapooya';
list[20] = 'apples';
delete list[19];
( var list[xx] would not work due to syntax error )
list[19] would be undefined.

Apart from the syntax error you get when using varbefore list[19] = 'kapooya', list[19] is undefined after the delete, not null.
Technically you are not creating a list but an object, or a map, or a hash, or a dictionary, however you wish to refer to it.
The correct syntax for working with lists, or in the case of javascript, Arrays, is var list= []; be aware that the delete operator doesn't work on array items.

Related

console gives a string isn't a function error

I'm creating a quiz and console shows a problem with split, that it's not a function, but it worked before. I've tried using toString method but it doesn't help, console says instead that can't read properties of null. If someone could help me, it would be appreciated.
let correctAnswer = document.getElementById("correct-answers");
document.querySelector(".check").onclick = function () {
/* Hide unneeded sections and showing scores */
quiz.classList.add("hidden");
correctAnswer.classList.remove("hidden");
/*Showing all previous scores */
const lastScore = localStorage.getItem("latestScore") || [];
const scoreDetail = lastScore.split(',');
scoreDetail.push(score);
localStorage.setItem("latestScore", scoreDetail);
let userScoreTemplate = `<h2>This Round's Score: ${score}</h2>`;
scoreDetail.map((items, index) => {
userScoreTemplate += `<h3>Score ${index}: ${items}</h3>`
});
let userScoreBoard = document.getElementById("user-score");
userScoreBoard.innerHTML = userScoreTemplate;
localStorage.getItem() will return a string.
You need adjust your code accordingly to default to a string in case the item is not defined:
const lastScore = localStorage.getItem("latestScore") || "";
In your code lastScore is an array, not a string, so the split method will not work on it. It works only on strings.You can use JSON.Parse like that. This will convert array data into javascript array.
const scoreDetail = JSON.parse(lastScore) || [];
scoreDetail.push(score);
And after that convert the array into a JSON string :
localStorage.setItem("latestScore", JSON.stringify(scoreDetail));
is latest score is a obj/array/string or what?
If it's an array/object then wrap localStorage.getItem in JSON.parse() so js can convert array data into js array
As per the error, You are trying to apply split on an array instead of a string.
Looks like, localStorage.getItem("latestScore") is undefined while you are trying to access it and it assigned an empty array to lastScore variable.
Hence, Instead of
const lastScore = localStorage.getItem("latestScore") || [];
Use
const lastScore = localStorage.getItem("latestScore") || "";

textContent Vs. innerText Cross Browser solution

I've been having a hard time with cross browser compatibility and scrapping the dom.
I've added data analytics tracking to ecommerce transactions in order to grab the product and transaction amount for each purchase.
Initially I was using document.querySelectorAll('#someId')[0].textContent to get the product name and that was working fine for every browser except internet explorer.
It took some time to figure out that it was the .textContent part that was causing ie problems.
Yesterday I changed .textContent to .innerText. From looking inside analytics it seems that the issue has been resolved for ie but now Firefox is failing.
I was hoping to find a solution without writing an if statement to check for the functionality of .textContent or .innerText.
Is there a cross browser solution .getTheText?
If not what would be the best way around this? Is there a simple solution? (I ask given my knowledge and experience with scripting, which is limited)
** added following comments **
If this is my code block:
// build products object
var prods = [];
var brand = document.querySelectorAll('.txtStayRoomLocation');
var name = document.querySelectorAll('.txtStayRoomDescription');
var price = document.querySelectorAll('.txtStayRoomSplashPriceAmount');
for(var i = 0; i < brand.length; i++) {
//set granular vars
var prd = {};
//add to prd object
prd.brand = brand[i].innerText;
prd.name = name[i].innerText;
prd.price = price[i].innerText;
prd.quantity = window.session_context_vars.BookingContext.Booking.ReservationLineItems[i].ReservationCharges.length/2;;
//add to prods array
prods.push(prd);
}
Then if I understand the syntax from the comments and the question linked to in the comment, is this what I should do:
// build products object
var prods = [];
var brand = document.querySelectorAll('.txtStayRoomLocation');
var name = document.querySelectorAll('.txtStayRoomDescription');
var price = document.querySelectorAll('.txtStayRoomSplashPriceAmount');
for(var i = 0; i < brand.length; i++) {
//set granular vars
var prd = {};
//add to prd object
prd.brand = brand[i].textContent || brand[i].innerText;
prd.name = name[i].textContent || name[i].innerText;
prd.price = price[i].textContent || price[i].innerText;
prd.quantity = window.session_context_vars.BookingContext.Booking.ReservationLineItems[i].ReservationCharges.length/2;;
//add to prods array
prods.push(prd);
}
So using or with a double bar || assigns the first non null value?
Re: your edit, not quite. The way to access methods or properties on an object (eg a DOM element) is to use dot notation if you have the name itself, or square brackets in case of variables/expressions (also works with strings, as in obj["propName"], which is equivalent to obj.propName). You can also just test the property against one element and use that from there on:
// build products object
var prods = [];
var brand = document.querySelectorAll('.txtStayRoomLocation');
var name = document.querySelectorAll('.txtStayRoomDescription');
var price = document.querySelectorAll('.txtStayRoomSplashPriceAmount');
for(var i = 0; i < brand.length; i++) {
//set granular vars
var prd = {};
//add to prd object
var txtProp = ("innerText" in brand[i]) ? "innerText" : "textContent"; //added string quotes as per comments
prd.brand = brand[i][txtProp];
prd.name = name[i][txtProp];
prd.price = price[i][txtProp];
prd.quantity = window.session_context_vars.BookingContext.Booking.ReservationLineItems[i].ReservationCharges.length/2;;
//add to prods array
prods.push(prd);
}
Regarding the line:
var txtProp = (innerText in brand[i]) ? innerText : textContent;
The in keyword checks an object to access the property (syntax: var property in object). As for the question notation (I made an error earlier, using ||, the correct thing to use was a :),
var myVar = (prop in object) ? object[prop] : false;
As an expression, it basically evaluates the stuff before the ?, and if it's true, returns the expression before the :, else the one after. So the above is the same as / a shorthand for:
if(prop in object){
var myVar = object[prop];
}
else{
var myVar = false;
}
Since you are checking between two properties only and wanting to assign one or the other, the shortest way would indeed be:
var txtProp = brand[i].innerText || brand[i].textContent;
It would basically test the first property, and if it were false or undefined, it would use the second one. The only reason I (pedantically) avoid using this is because the first test of a || b would fail even if a existed but just had a value of 0, or an empty string (""), or was set to null.

javascript wierdness returning value

Hi I am new with javascript, there is a problem that is driving me crazy:
what is the difference between an object staticly declared as this one :
{$or:[{tc_clpar_id:4,tc_par_id:{$in:[79,80]}},{tc_clpar_id:5,tc_par_id:{$in:[105,106]}}]}
and an object costruct at run-time, with this function:
function buildQuery(self,setting,query){
var query = {$or:[]};
cl = 'tc_cl'+self.family+'_id';
att ='tc_'+self.family+'_id';
keys = Object.keys(setting);
for( var k=0;k<keys.length;k++){
ch = keys[k];
var q = {};
q[cl] = ch;
q[att] = {$in:setting[ch]};
query.$or.push(q);
}
return query;
this object is used as query for the node-mongodb-native driver, the first one works, the object return by the function in correct, I checked the two object with assert.deepEqual, there are no errors, but using the produced object I get an empty resultset, I do not have any clue about the problem, I thought maybe something strange with the scope as the function is a method of another object, or maybe with the garbage collector.

got stuck with this set of code in jquery validate

var formRules = $(this).data('rules');
var formValues = $(this).data('values');
if(formRules || formValues){
var rulesArray = formRules.split(',');
var valuesArray = formValues.split(',');
for(var i=0; i < rulesArray.length; i++){
//alert(rulesArray[i]);
$.validationEngine.defaults.rulesArray[i] = valuesArray[i];
}
}
else{
return false;
}
This throws an error like following
Error: TypeError: $.validationEngine.defaults.rulesArray is undefined
Source File: http://localhost:8380/javascript/jquery.validationEngine.js
Line: 2092
I cannot find the problem with this code.Any help is welcome
EDIT:
I am trying to set the global options eg:scroll using the for loop.
The formRules string will have these options comma seperated and the corresponding values in the formValues string.
So i am expecting it to come like $.validationEngine.defaults.scroll = true;
change this line
$.validationEngine.defaults.rulesArray[i] = valuesArray[i];
to this
$.validationEngine.defaults[rulesArray[i]] = valuesArray[i];
rulesArray is not a child of $.validationEngine.defaults. The values stored in your rulesArray are. The syntax in my second code block references everything properly.
This is called Bracket Notation, a way to get an object's property using any sort of valid calculation (like rulesArray[i], or "myStringPropertyName"). see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Member_Operators for other methods.

javascript message queue

I am using javascript to create a message queue, say for example I want to store the messages "hello" and "word" to user with id "123", I am using the following to set and retrieve them.
var messages = [];
var userId = 123;
messages[userId].push("hello");
messages[userId].push("word");
needless to say, this is not working, damn arrays! How can I make this work, keeping it as simple as possible?
Thanks in advance
You need an array ([]) for every user:
var messages = {};
var userId = 123;
messages[userId] = ["hello", "word"];
You can use push too:
var messages = {};
var userId = 123;
messages[userId] = [];
messages[userId].push("hello");
messages[userId].push("word");
messages[userId] does not exist.
You need to put an array there:
messages[userId] = [];
well, technically you could push elements as properties of an object, which you have created and then iterate thorugh its properties.

Categories