What to do if there is no data in localStorage? - javascript

I'm in a dilemma, I have a search engine which I keep the last results, everything perfect until there.
The problem is that I do not know what to do if I do not have items already saved, ie if it is the first time I search.
if(localStorage.getItem("searchResults") === null) {
// I do not know what to do here ...
}
else {
// Here the code is supposed to do what it has to do
}
Should not I do anything, should I save an empty string, or would I have to change the logic I'm working on?
What are your friends, what are you doing? Thank you

I would have a variable called "noResults", and set it to false, when search results are 0, or you can make it fetch results from server. It's all about context and logic

You could set it to N/A:
if(localStorage.getItem("searchResults") === null) {
localStorage.setItem("searchResults", "N/A");
}
else {
// Here the code is supposed to do what it has to do
}
Or use the following, and when you check if searchResults is null, last search result should be empty.
if(localStorage.getItem("searchResults") !== null) {
// Here the code is supposed to do what it has to do
}

Maybe you don't need an if statement. The if statement provides you with code blocks that can be executed for truthy or falsely expressions.
Instead, use a logical OR || to define a default value.
var results = localStorage.getItem('searchResults') || 'No results...';

Related

JavaScript studies. How Map() code are being executed?

Good evening.
I'm really struggling to get my head around this and I'm not sure if I'm missing something really stupid, but here is my code and my question.
const question = new Map();
question.set('question', 'What is the official name of the latest major JavaScript version?');
question.set(1, 'ES5');
question.set(2, 'ES6');
question.set(3, 'ES2015');
question.set(4, 'ES7');
question.set('correct', 3);
question.set(true, 'Correct answer :D');
question.set(false, 'Wrong, please try again!');
for (let [key, value] of question.entries()) {
if (typeof(key) === 'number') {
console.log(`Answer ${key}: ${value}`);
}
}
const ans = parseInt(prompt('Write the correct answer'));
console.log(question.get(ans === question.get('correct')));
Can someone please explain to me how, when I insert the right value into the prompt box; the interpreter?... knows to check the next line of code to display "Correct" or "Wrong in the console? depending on my input. I know we have a key of correct and its value is set to 3 but when do we tell it to execute the next lines of code depending on my answer? Does it just parse through the whole code, see a true statement and then executes whatever it is attached too, else execute the false statement? How, why? Apologies if I'm not coming through very clearly.
Your Map has an entry for key true and one for false. One of them is retrieved by using a key that corresponds to this expression:
ans === question.get('correct')
This expression returns true when the given answer is equal to the correct one, and false otherwise. This boolean result is then used as key for the next lookup in your set:
question.get(ans === question.get('correct'))
This effectively retrieves the value for either false or true -- as stored in your Map. And so the correct phrase is retrieved (and displayed).
If you would write that magic line a bit more verbose, it could look like this:
let output;
if (ans === question.get('correct')) { // get() returns 3 here.
output = question.get(true); // This retrieves 'Correct answer :D'
} else {
output = question.get(false); // This retrieves 'Wrong, please try again!'
}
console.log(output);
But realise how ans === question.get('correct') is a boolean expression, meaning it represents false or true, exactly what you want to pass as value to question.get in order to retrieve the phrase to be output.
So, instead of the if construct you can do:
let isCorrect = (ans === question.get('correct')); // false or true
let output = question.get(isCorrect); // This retrieves one of the two phrases
console.log(output);
And what those three lines do can be shortened into just one line:
console.log(question.get(ans === question.get('correct')));
NB: using Maps in this way doesn't look right. You should really use an array for the questions, and plain object(s) for the other stuff.

My Bools Aren't working?

I am trying to make a "Battleship" like game. Most of my board is supposed to be "missed" tiles, and only a few are supposed to be tiles with submarines on them for a "hit". The problem is that whenever I run my program, I cannot tell if it is ignoring my bool or if it isn't understanding what I coded, because everything I click is a "hit".
var cellClick=function(clicked)
{
var cell=clicked.target;
if(! cell.isEmpty) return;
if(cell.isSub=false)
{
cell.style.backgroundImage='url("missed.png")';
cell.style.backgroundSize='constrain';
}
else
{
cell.style.backgroundImage='url("hit.png")';
cell.style.backgroundSize='constrain';
cell.exploded=true;
}
cell.isEmpty=false;
console.log('click');
};
var waterCell=[[],[],[],[],[],[],[],[],[],[]];
for(var row=0;row<10;row++)
{
for(var column=0;column<10;column++)
{
waterCell[row][column]=document.createElement("div");
waterCell[row][column].style.width='10%';
waterCell[row][column].style.height='10%';
waterCell[row][column].style.position='absolute';
waterCell[row][column].style.left=(column*10)+'%';
waterCell[row][column].style.top=(row*10)+'%';
waterCell[row][column].style.backgroundImage='url("water_cell.jpg")';
waterCell[row][column].style.backgroundSize='contain';
gameBoard.appendChild(waterCell[row][column]);
waterCell[row][column].row=row;
waterCell[row][column].column=column;
waterCell[row][column].isEmpty=true;
waterCell[row][column].isSub=false;
waterCell[row][column].exploded=false;
}
}
//trying to make random subs
for(var i=0;i<5;i++)
{
row=Math.round(Math.random()*10);
column=Math.round(Math.random()*10);
waterCell[row][column].isSub=true;
}
gameBoard.addEventListener('click',cellClick,false);
Your code
if(cell.isSub=false) {
is assigning false to the property isSub of cell. The assignment's result is then tested by if, which is false. That's why the condition is never met and the else-branch is processed. Obviously, your intention was
if(cell.isSub==false) {
Maybe try swapping the branches of if statement and test for truthy value in cell.isSub instead making the code simpler:
if ( cell.isSub ) {
// it's a hit
} else {
// it's a miss
}
If you require to keep this order of branches testing for falsy values can be simplified as well by using negation operator:
if ( !cell.isSub ) {
// it's a miss
} else {
// it's a hit
}
One last tip: don't set custom properties of a DOM element as those perform poorly. Even worse, they are perfect soil for memory leakages when putting Javascript objects or functions. Thus, keep the two worlds - your Javascript and your HTML/DOM - as separated as possible and train yourself not to put additional data into Javascript-representations of objects managed in context of DOM. Use a separate description in pure Javascript (e.g. two-dimensional array) for tracking position of your subs and create a DOM representing that internal data set, only.

Firebase won't save keys with null values

I have an object like:
var _json = { "objects":[{
"type":"path", "originX":"center", "originY":"center", "left":48.59,
"top":132.5, "width":64.5,"height":173, "fill":null,"stroke":"#3f7cc4",
"strokeWidth":12,"strokeDashArray":null
}]}
I save this object using Firebase as:
var myDataRef = new Firebase(<...>);
myDataRef.child("saved_projects").child(authData.uid).update({'P3': _json});
But, when I retrieve the same using Firebase on method and get the value as:
snapshot.val()
I get the object but keys with null values got removed i.e. I only got:
{"objects":[ {"type":"path", "originX":"center",
"originY":"center","left":48.59, "top":132.5,"width":64.5,
"height":173, "stroke":"#3f7cc4","strokeWidth":12
}]}
This is causing me some weird issues since I'm using Fabric.js and it needs these values.
Please help!
EDIT / UPDATE(Hack)
For the time being, I'm using a weird HACK, before storing the object to Firebase I'm converting all the null values to 0. But I want to know a nicer way to do.
function recursivelyReplaceNullToZero(j) {
for (var i in j){
if (typeof j[i] === "object") {
recursivelyReplaceNullToZero(j[i]);
}
if (j[i] === null) {
j[i] = 0;
}
}
}
recursivelyReplaceNullToZero(_json);
For the time being I'm using a weird HACK, before storing the object to Firebase I'm converting all the null values to 0. But I want to know much nicer way, please!
function recursivelyReplaceNullToZero(j) {
for (var i in j){
if (typeof j[i] === "object") {
recursivelyReplaceNullToZero(j[i]);
}
if (j[i] === null) {
j[i] = 0;
}
}
}
recursivelyReplaceNullToZero(_json);
fill would be a type string and those can be empty in Firestore.
strokeDashArray would be a type array and those can contain empty strings as well (among other data types). See image below which is a screenshot of Firestore. You are correct about null though, it won't store properties with value null.
Remember though that Firestore is a document database, and is schema-less - meaning that not every document is required to have all fields (semi-structured).
So, instead of storing value-less properties, simply handle the possibility that the property may not be there in your code, e.g.,
if(doc.exists){
if(doc.data().fill){
// now you do what you want with the fill property
} else {
// there is no fill data
}
}
This is expected behavior. AFAIK json systems work like this.
You should instead in your code set nulls for the keys that are not present in the database.
As an analogy: think of the leading zeroes - you DON'T write in front of a number.

JQuery - $(#).remove() vs document.getelementbyid().remove

Originally i had a remove function like this:
function ViewWorkflowDetail(btn, workflowId) {
$("#workflowDetailPanel").remove();
if (document.getElementById("workflowDetailPanel") == null) {
// Do something usefull here
}
}
Which worked brilliantly. Yet (in the spirit of using as much JQuery as possible) I changed it to:
function ViewWorkflowDetail(btn, workflowId) {
$("#workflowDetailPanel").remove();
if ($("#workflowDetailPanel") == null) {
// Do something usefull here
}
}
But right now $("#workflowDetailPanel") is never null anymore. If i change it back again (to document.getElementById), then there is no problem anymore. Why does the second option keeps on finding that div? Are the JQuery objects somehow maintained in some sort of cache?
Note: Exactly the same setup/data were used to test both cases.
It will never be null, since jQuery returns an empty array if the element does not exist, you must check the length of the array
if ($("#workflowDetailPanel").length > 0) {
// Do something usefull here
}

If statement in jQuery plugin

I have a jQuery plugin with an if statement in it.
For some strange reason (probably it is just me screwing things up) it always gets in the else part even when the url's are the same.
if (opts.startUrl == track.permalink.url) {
var active = true;
} else {
alert('|'+opts.startUrl+'| |'+track.permalink_url+'|');
var active = false;
}
Check it out # http://dev.upcoming-djs.com
The surrounding code uses track.permalink_url, while the if block evaluates track.permalink.url (which is always undefined), so this condition:
opts.startUrl == track.permalink.url
Always evaluates to false
Update: as #brianpeiris points out, the correct fix here would be to change the condition to:
opts.startUrl == track.permalink_url
Start printing both the values and see what is the difference , otherwise do this
if (opts.startUrl.toLowerCase() == track.permalink.url.toLowerCase())

Categories