Javascript boolean logic error - javascript

My code:
var old = localStorage.getItem('GotoBeginning');
console.log("old is "+ old);
if (old===true) {
console.log("Returning true");
$("#gobeg").prop('checked', true);
return true;
} else {
console.log("Returning false");
$("#gobeg").prop('checked', false);
return false;
}
The value in localStorage for GotoBeginning is true.
My console.log shows:
old is true
Returning false
I expected the following output:
old is true
Returning true

The storage api in the browser only stores strings. This should work:
if (old === 'true') {
// ^ ^
} else {
}
As mentioned in a comment by IrkenInvader, you can extract the proper type like so:
var old = JSON.parse(localStorage.getItem('GotoBeginning'))
// now old will be a proper boolean so this will work
if (old) {
} else {
}

Related

checking with boolean values not working correctly

please see edit #1 - I'm working on a Vue.js and am changing a co-workers code. The goal is to check that we have a user in our Vuex store and if not alert the user to login / signup. When not logged in, it is returning false but the 'TOGGLE_LIKED' is still being called.
It currently looks like this:
check(){
if (typeof this.$store.state.user === 'undefined' || !this.$store.state.user) {
alert('please signin in the upper-right'); /* eslint-disable-line no-alert */
return false;
}else{
return true;
}
},
toggleLiked() {
if (this.check()) {
this.isRunningToggle = true;
this.$store.dispatch('TOGGLE_LIKED', this.item).then(() => {
this.isRunningToggle = false;
});
What is wrong with the code so that if you are not logged in, the 'TOGGLE_LIKED' path isn't called?
edit #1
so if I switch to an event-bus call like this:
if (EventBus.$emit('checkLoggedIn')) {
this.isRunningToggle = true;
this.$store.dispatch('TOGGLE_LIKED', this.item).then(() => {
this.isRunningToggle = false;
});
}
with checkLoggedIn in the root component as:
EventBus.$on('checkLoggedIn', () => {
console.log(this.$store.state.user);
if (typeof this.$store.state.user === 'undefined' || !this.$store.state.user) {
alert('please signin in the upper-right');
return false;
}else{
alert('this is true');
return true;
}
});
The first alert is called but the second ISN'T. So if we are returning false, why does the check return "effectively" true?

How do I ensure an array has no null values?

I would like test my Array (input value) before submit my form.
My array with value :
const fields = [
this.state.workshopSelected,
this.state.countrySelected,
this.state.productionTypeSelected,
this.state.numEmployeesSelected,
this.state.startAt
];
I've try this :
_.forEach(fields, (field) => {
if (field === null) {
return false;
}
});
alert('Can submit !');
...
I think my problem is because i don't use Promise. I've try to test with Promise.all(fields).then(());, but i'm always in then.
Anyone have idea ?
Thank you :)
The problem is that even though you're terminating the lodash _.forEach loop early, you don't do anything else with the information that you had a null entry.
Instead of lodash's _.forEach, I'd use the built-in Array#includes (fairly new) or Array#indexOf to find out if any of the entries is null:
if (fields.includes(null)) { // or if (fields.indexOf(null) != -1)
// At least one was null
} else {
// All were non-null
alert('Can submit !');
}
For more complex tests, you can use Array#some which lets you provide a callback for the test.
Live example with indexOf:
const state = {
workshopSelected: [],
countrySelected: [],
productionTypeSelected: [],
numEmployeesSelected: [],
startAt: []
};
const fields = [
state.workshopSelected,
state.countrySelected,
state.productionTypeSelected,
state.numEmployeesSelected,
state.startAt
];
if (fields.indexOf(null) != -1) {
console.log("Before: At least one was null");
} else {
console.log("Before: None were null");
}
fields[2] = null;
if (fields.indexOf(null) != -1) {
console.log("After: At least one was null");
} else {
console.log("After: None were null");
}
You do not need to use promises unless there is an asynchronous operation (for example if you are getting that array from your server).
If you already have that array you can do something like:
// Using lodash/underscore
var isValid = _.every(fields, (field) => (field!==null)}
// OR using the Array.every method
var isValid = fields.every((field)=>(field!==null))
// Or using vanilla JS only
function checkArray(array){
for(var i = 0; i < array.length ; i ++){
if(array[i]===null){
return false;
}
}
return true;
}
var isValid = checkArray(fields);
// After you get that value, you can execute your alert based on it
if(!isValid){
alert('Something went wrong..');
}
Try this simple snippet
var isAllowedToSubmit = true;
_.forEach(fields, (field) => {
if (!field) {
isAllowedToSubmit = false;
}
});
if(isAllowedToSubmit)
alert('Can submit !');
You can do that without library:
if (fields.some(field => field === null)) {
alert('Cannot submit');
} else {
alert('Can submit');
}
You don't need to use lodash, you can do this in simple vanilla javascript. Simply iterate over each field and if an error occurs set your errors bool to true
let errors = false;
fields.forEach(field) => {
if(field === null || field === '') {
errors = true;
}
});
if (!errors) {
alert('Yay no errors, now you can submit');
}
For an es6 you can use.
const hasNoError = fields.every((field, index, selfArray) => field !== null);
if (!hasNoError) {
alert('yay It works');
};
Have a look at Array.every documentation Array every MDN documentation

How to invalidate localStorage after breaking change

I have this little piece of code which is allowing me to check if user has localStorage set before I've made breaking changes in it's format.
var sw =
{
storage: {
// change this date when you create breaking changes in local storage
// any local storage set before this time will be invalidated & set again
lastBreakingUpdateTime: new Date(2017, 4, 24),
local: {
set: function(key, value) {
try {
window.localStorage.setItem(key.toString(), value.toString());
return true;
}
catch(e) {
return false;
}
},
get: function(key) {
var value = window.localStorage.getItem(key.toString());
if (value === 'true')
return true;
if (value === 'false')
return false;
// isNan returns false for empty string
// empty string is considered 0 by isNaN, but NaN by parseInt :)
if (isNaN(value) || value === '')
return value;
// return value converted to number
return +value;
},
markAsSetNow: function() {
sw.storage.local.set('timeWhenSet', new Date());
},
isOutdatedOrNotSet: function() {
var lastSetTime = sw.storage.local.get('timeWhenSet');
if (!lastSetTime || Date.parse(lastSetTime) <= sw.storage.lastBreakingUpdateTime)
return true;
return false;
}
}
}
}
Issue with this code is that in javascript Date.Parse is unreliable accross browsers - each browser has different implementation. I need to modify this code so that it works reliably in every major browser.
Use time in ms to compare the dates in order to check the cache:
const ms = new Date().getTime();
It is cross-browser
In the end I have decided to use a format version number, like ayinloya has suggested in comments. Here is my complete local storage handling code, if someone wants to use in their apps.
var appName =
{
storage: {
// increment this when you create breaking changes in local storage format
// versions must start from 1, version 0 is invalid
formatVersion: 1,
// type can be 'localStorage' or 'sessionStorage'
available: function(type) {
try {
var storage = window[type],
x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return false;
}
},
local: {
// Use this function over window.localStorage.setItem() because
// localStorage.setItem() or sessionStorage.setItem() may throw
// an exception if the storage is full.
// in Mobile Safari (since iOS 5) it always throws when the user
// enters private mode (Safari sets quota to 0 bytes in private mode,
// contrary to other browsers, which allow storage in private mode,
// using separate data containers).
set: function(key, value) {
try {
window.localStorage.setItem(key.toString(), value.toString());
return true;
}
catch(e) {
return false;
}
},
get: function(key) {
var value = window.localStorage.getItem(key.toString());
if (value === 'true')
return true;
if (value === 'false')
return false;
// isNan returns false for empty string
// empty string is considered 0 by isNaN, but NaN by parseInt :)
if (isNaN(value) || value === '')
return value;
// return value converted to number
return +value;
},
setFormatVersion: function() {
appName.storage.local.set('formatVersion', appName.storage.formatVersion);
},
isOutdatedOrNotSet: function() {
var version = appName.storage.local.get('formatVersion');
if (!version || version < appName.storage.formatVersion)
return true;
return false;
}
}
}
}

How to check if eval returns nothing in JS

If I want to check if an eval function returns nothing, how do I do it?
I tried to do something like:
if (eval("iwuoinuvwoienvuwope") == "") {
// Do something
alert("Oh NO!");
}
But when I do like that nothing happends.
Here is my full code:
function calc() {
var cal = prompt("Your math....", "1 + 1");
if (cal == null) {
alert("If you don't have a math problem you can gtfo!");
} else if (cal == false) {
alert("If you don't have a math problem you can gtfo!");
}
/* Here I Check if eval is empty */
/* Here it doesn't work */
else if (eval(cal) == "") {
alert("Could you be more specific");
}
/* */
else {
alert("The answer is " + eval(cal));
}
}
<button onclick="calc();">Calculator</button>
eval(code) returns "the completion value of evaluating the given code. If the completion value is empty, undefined is returned." MDN
In your case, a valid math expression returns a Number. Thus you would have to check for typeof result == "Number". If you want to exclude NaN, Infinity and the like, perform additional checks e.g. by isFinite(result).
If you are trying to build a calculator, you should either be expecting a response, an exception or null.
try {
if (r === undefined) {
} else {
// handle response
}
} catch (error) {
// invalid
}
Validating whether it's a Number, and if the mathematical formula is valid will help you identity possible error outputs.

How to respond to SyntaxError in javascript

I get data back from a php server and sometimes it tosses in warnings. These warnings cause the parsing of the response to throw a syntax error which defies all try/catch code I have in place and just stops processing, leaving complex objects in partial states that can't be recovered.
How can I catch these errors? I want to have a chance to get the object back into some steady state.
Ideally, I would not receive answers stating that I should rethink architecture or change php settings. I would like to know how to respond to SyntaxErrors being thrown by JSON.parse().
Thank you,
Jeromeyers
EDIT:
It has come to my attention that the problem is more complex than I originally thought. This is the code that doesn't catch the SyntaxError:
generateSubmissionSuccessCallback: function (reloadOnSave) {
var self = this;
var submissionCallback = function(response) {
var processingError = false;
try
{
var responseObject = {};
if (self.isAspMode())
{
if (typeof response !== 'object') // Chrome auto-parses application/json responses, IE & FF don't
{
response = JSON.parse(response);
}
responseObject = {
entity: response.Payload,
success: response.Success,
message: response.Exception
};
if (jQuery.isArray(response.ValidationErrors))
{
responseObject.message += ' \r\n\r\nValidation Errors\r\n';
for (var i = 0, maxi = response.ValidationErrors.length; i < maxi; i++)
{
var error = response.ValidationErrors[i];
responseObject.message += error.Error + '\r\n';
}
}
}
else
{
responseObject = JSON.parse(response);
}
if (!responseObject || (responseObject.success !== undefined && responseObject.success !== true))
{
processingError = true;
var message = responseObject ? responseObject.message : response;
ErrorHandler.processError(
'An attempt to save failed with following message: \r\n' + message,
ErrorHandler.errorTypes.clientSide,
null,
jQuery.proxy(self.validatingAndSubmittingFinallyFunction, self));
}
else
{
// If this is a parent metaform, reload the entity, otherwise, close the metaform
if (self.metaformType === 'details')
{
if (self.substituteWhatToDoAfterSavingCallback)
{
self.substituteWhatToDoAfterSavingCallback(responseObject);
}
else if (reloadOnSave)
{
self.reloadCurrentEntity(true, responseObject.entity);
}
if (self.doesViewOutlineDefinePostSaveHook())
{
self.viewOutline.functions.postSaveHook(self);
}
}
else if (self.metaformType === 'childDetails')
{
// Reload the Grid by which this form was made
if (self.associatedGridId)
{
Metagrid.refresh(self.associatedGridId);
}
if (self.parentMetaform.associatedGridId && self.childPropertyName)
{
var annotation = self.parentMetaform.getAnnotationByPropertyName(self.childPropertyName);
if (annotation && annotation.hasPropertyOptions('updateParentMetaformAssociatedGrid'))
{
Metagrid.refresh(self.parentMetaform.associatedGridId, self.parentMetaform.entityId);
}
}
if (self.substituteWhatToDoAfterSavingCallback)
{
if (self.doesViewOutlineDefinePostSaveHook())
{
self.viewOutline.functions.postSaveHook(self);
}
self.substituteWhatToDoAfterSavingCallback(responseObject);
}
else
{
if (self.doesViewOutlineDefinePostSaveHook())
{
self.viewOutline.functions.postSaveHook(self);
}
self.disposeMetaform();
}
}
}
}
catch (ex)
{
processingError = true;
ErrorHandler.processError(
"Please immediately inform the authorities that: \r\n\r\n" + typeof response === 'string' ? response : JSON.parse(response) + "\r\n\r\nand:\r\n\r\n " + ex.message,
ErrorHandler.errorTypes.clientSide,
null,
jQuery.proxy(self.validatingAndSubmittingFinallyFunction, self));
}
finally
{
// If we are reporting an error to the user then we can't reset these state variables
// because in the case where this is a child form, the parent will close the form
// before the user has read the error.
if (!processingError)
{
self.validatingAndSubmittingFinallyFunction();
}
}
};
return jQuery.proxy(submissionCallback, self);
}
There's really a lot going on in there, and a lot of structure that it fits into. I don't know if including it will really help.
Assuming you are talking about JSON and it raising an error (and not actual JavaScript being served to the page):
var data;
try{
data = JSON.parse(jsonString);
}catch(e){
// handle the error here, if you like
}
if (typeof data !== "undefined"){
// Yay, we got some!
}
Read more about try...catch at MDN.
For example (from Chrome's console):
> try{ JSON.parse('3/') }catch(e){ console.log('oh no!') }; console.log('OK!')
"oh no!"
"OK!"

Categories

Resources