How to determine if a static variable has been used? - javascript

According to the IE Debugger my static variable
link_update.previous_element
is set to undefined, the first time through the function.
However when I add in a test for undefined or 'undefined' in parantheses it does not select it properly as I show in the code below.
How do I detect first use of a static variable?
function link_update( link_display )
{
current_element = document.getElementById( link_display )
current_element.style.opacity = 1;
if( link_update.previous_element != undefined)
{
link_update.previous_element.style.opacity = 0;
}
link_update.previous_element = current_element;
}

Use typeof:
if(typeof link_update.previous_element != 'undefined')
You may also like to remove the semicolon.

Related

Common jQuery function for conditional undefined variable

Suppose, I'm doing something like below in the same javascript file (eg. app.js):
// triggers in both add and edit mode
var purchase = $('.purchase-selector').doSomething();
// triggers only on edit mode where, purchase_data is available
if( typeof purchase_data !== 'undefined' ) {
purchase.anotherThing(purchase_data);
}
// triggers in both add and edit mode
var sales = $('.sales-selector').doSomething();
// triggers only on edit mode where, sales_data is available
if( typeof sales_data !== 'undefined' ) {
sales.anotherThing(sales_data);
}
The issue is, without the Purchase Edit mode there's no purchase_data variable is available. Same is true for the sales_data where it's only available on the Sales Edit mode.
The code is working fine, but actually, I'm doing it against the DRY principle (my code is a way too lengthy). So I tried making a simple method to remove the DRY.
var the_thing = function(selector, edit_data) {
var thing = selector.doSomething();
if( typeof edit_data !== 'undefined' ) {
thing.anotherThing(edit_data);
}
};
the_thing($('.purchase-selector'), purchase_data);
the_thing($('.sales-selector'), sales_data);
But the issue is it's generating Uncaught ReferenceError: purchase_data is not defined (same for the sales_data too).
So I tried something like below:
if( typeof purchase_data === 'undefined' ) {
var purchase_data;
}
the_thing($('.purchase-selector'), purchase_data);
if( typeof sales_data === 'undefined' ) {
var sales_data;
}
the_thing($('.sales-selector'), sales_data);
But it's making the purchase_data (object) to undefined as well.
In edit mode:
console.log(typeof purchase_data);
is returning:
object
but with the following code:
console.log(typeof purchase_data);
if( typeof purchase_data === 'undefined' ) {
var purchase_data;
}
console.log(typeof purchase_data);
It's showing:
undefined
undefined
Can't I use a concept of function in this case?
You are getting the error because your purchase_data and sales_data variables need to be defined before they can be used (even when checking to see if they were assigned a value).
What you can do is, create a function to check if a variable has been assigned a value:
function isUndefined(valor) {
return (typeof valor === 'undefined');
}
Then, among your other code, you need to define said variabled before they are used in any function:
var purchase_data;
var sales_data;
Then you can make reference to the variables in which if no values have been assigned, they will be of type undefined which you can check using the above function:
var the_thing = function(selector, edit_data) {
var thing = selector.doSomething();
if(!isUndefined(edit_data)) {
thing.anotherThing(edit_data);
}
};
the_thing($('.purchase-selector'), purchase_data);
the_thing($('.sales-selector'), sales_data);
The variable purchase_data has to be defined for using it as an argument for the function. Because it is not defined, it cannot be evaluated before the actual call of the function. This causes the error.
When you say var purchase_data;, the variable is known, so it can be used as an argument. But it still has no value, so typeof is undefined.

JavaScript API Response - Check if variable exists

In an API response, I want to check if a variable exists. If it doesn't, I want to assign it a blank value:
if(!data3.fields[i+2].values.value[0]) {
data3.fields[i+2].values.value[0] = "";
} else {
break;
}
Error in the console is:
Uncaught TypeError: Cannot read property 'value' of undefined
This confuses me because I thought that's exactly what my if the statement was checking. Any ideas what's going on here?
The if check won't protect you from trying to use an undefined variable. In your instance the values property is undefined. If you wanted to test for that you would need to first check that specific property
if(data3.fields[i+2].values !== undefined && data3.fields[i+2].values.value[0]){
//do something with data3.fields[i+2].values.value[0]
}
additionally, if you are in a scenario where you don't even know if data3 exists (for example you are checking for the existence of a third party script, or something else in your environment) you would need to use the typeof operator to be safe. E.G.
if(typeof(ga) !== 'undefined'){ //typeof returns a string. This would be testing for google analytics on a page.
It doesnt work like PHP does (which checks the whole 'chain'). In your example, you actually check if .value[0] of values exists, but dont check if values exists. The full version should be:
if( data3 && && data3.fields[i+2] && data3.fields[i+2].values && !data3.fields[i+2].values.value[0]) {}
In your code ata3.fields[i+2].values is undefined, and you're trying to access value[0] of 'undefined'
Or slightly more simplefied, if you wand to test if d has a value, you have to make sure that a, b and c aldo have a value:
if( a && a.b && a.b.c && !a.b.c.d){ /* ... */ }
You can remove checks on the left side of the checks if you are sure those exist. E.g.: If you know that a.b always exist, you can simplefy:
if( a.b.c && !a.b.c.d){ /* ... */ }
If you really want to make sure the complete property chain is not undefined you have to check every single step and the later ones won't be executed if at least && condition is false.
if (data3 && data3.fields && data3.fields[i+2] && data3.fields[i+2].values && data3.fields[i+2].values.value && data3.fields[i + 2].values.value[0]) {
data3.fields[i + 2].values.value[0] = "";
} else {
break;
}
Another way would be to just do it and catch the exception:
try {
data3.fields[i + 2].values.value[0] = "";
} catch (e) {
break;
}
The error is telling you that data3.fields[i+2].values is undefined. You can't check for a property .value on undefined.
You'd need to verify each property/index belongs along the way if you always want that nested path to default to an empty string.
if (data3.fields[i+2] === undefined) {
data.fields[i+2] = {};
}
if (data3.fields[i+2].values === undefined) {
data3.fields[i+2].values = {};
}
if (data3.fields[i+2].values.value === undefined) {
data3.fields[i+2].values.value = [];
}
// and finally your empty string assignment
if (data3.fields[i+2].values.value[0] === undefined) {
data3.fields[i+2].values.value[0] = '';
}
Depending on your requirements, you might be able to get away with assigning a stub as soon as you know data3.fields[i+2] is undefined.
if (data3.fields[i+2] === undefined) {
data3.fields[i+2] = {
values: {
value: ['']
}
};
}

How to get element id as function parameter

I am studying as front end developer. I am new to javascript. And i got this problem when i execute a js from backend passing some elements id. It displays some error Cannot read property 'addEventListener' of null.
My js:
function disableOtherCheckBoxGrpScrolls(elementsContainerId) {
console.error("Elements id from backend: " + elementsContainerId);
var container = document.getElementById(elementsContainerId);
// I am checking here length of elements
console.error("Elements length : " + container.length);
// It displays Elements length : undefined
container.addEventListener('mousewheel', function(e){
if (!$(this).hasScrollBar()) return;
// If container div has a scrollbar it will do nothing
var event = e.originalEvent,
d = event.wheelDelta || -event.detail;
this.scrollTop += (d < 0 ? 1 : -1) * 30;
e.preventDefault();
}, {passive: false});
}
Any solution of this ?
And my backend passing elements id
if (!isMobile)
JSUtil.execFn("disableOtherCheckBoxGrpScrolls", checkboxGrp.getElementsContainerId());
Guys i solved my problem :). But i don't understand well how this working. My solution is:
function disableOtherCheckBoxGrpScrolls(elementsContainerId) {
console.error('containerId: ' + elementsContainerId);
// First is element undefined or Not rendered to DOM my opinion
(function() {
if (typeof elementsContainerId === "undefined") {
throw new Error("elementsContainerId parameter is undefined");
}
var container = document.getElementById(elementsContainerId);
console.error("Elements ID : " + container.length);
container.addEventListener('mousewheel', function(e) {
if (!$(this).hasScrollBar()) return;
// logger.debug('has scroll');
var event = e.originalEvent,
d = event.wheelDelta || -event.detail;
this.scrollTop += (d < 0 ? 1 : -1) * 30;
e.preventDefault();
}, { passive: false });
})();
}
And i thought maybe js worked before html elements not loaded thats i got null and undefined error. By the way thanks for all comments and answers :).
Be sure to pass an function parameter while calling.
disableOtherCheckBoxGrpScrolls('yourIDElement');
You should check that your elementsContainerId parameter isn't undefined or null. In some place, you are calling the disableOtherCheckBoxGrpScrolls without a parameter, with an undefined variable, with a variable which value is null.
You could check that elementsContainerId is not undefined or null just before your logic and throw an error if condition is true. In this way, you will instantly notice if your are passing a wrong parameter to your function.
function disableOtherCheckBoxGrpScrolls(elementsContainerId) {
if(typeof elementsContainerId === "undefined" || elementsContainerId === null) {
throw new Error("elementsContainerId parameter is undefined or null");
}
// ...
}
Also, after the first validation, you could check if the element with the specified id exists (just to be shure that the mousewheel event is bound)

Get value if all objects in chain exist, get fallback value if not

Feel kind of stupid to ask..
I want to get something like this:
var value = $scope.settings.paper.font.color || 0;
The problem is that some of the middle objects may not exist.
Is there an ultimate way to get value if all "object chain" exists and get some fallback if not?
For example, in line above if all objects exists, we may return value of color, but if only $scope.settings exists, and there's no paper object in it, i will get an error, not 0.
First of all: There is no builtin function for it.
Shortest generic solution
Simply wrap it into a try - catch
try {
// handles defaultVal if d is undefined
yourVar = typeof a.b.c.d === 'undefined' ? defaultVal:a.b.c.d;
} catch (e) {
// handles defaultVal if a,b or c are undefined
yourVar = defaultVal;
}
Alternative solution
You could use the following function to safely traverse an object (gv - for getValue):
var gv = function(scope, chainStr, defaultValue) {
var chain = chainStr.split('.');
for (var i = 0; i < chain.length; i++) {
var newScope = scope[chain[i]];
if (typeof newScope !== 'undefined') {
scope = newScope;
} else {
return defaultValue;
}
};
return newScope;
};
Like this:
var a = {b:{c:{d:3}}};
console.log(gv(window, 'a.b.c.d', -1));
// 3
console.log(gv(window, 'a.b.c.e', -1));
// -1
console.log(gv(a, 'b.c.d', -1));
// 3
console.log(gv(a, 'b.c.e', -1));
// -1
Sure, just check for the existence of $scope and each property in its namespace:
var value = (typeof $scope != 'undefined' && $scope.settings && $scope.settings.paper && $scope.settings.paper.font && $scope.settings.paper.font.color) || 0;
The last part of the statement in parenthesis will return the value of .font
Example: http://jsfiddle.net/silkster/gM8uh/
You can also make use of build in $parse service:
var value = $parse('settings.paper.font.color || 0')($scope);
It will make all necessary checks behind the scene.
Demo: http://plnkr.co/edit/1GLb5PEvxMzPMYc5ZxZn?p=preview

IE9 javascript error when variable is null or undefined

I have a textarea where I use javascript to check if there's something writen on it:
if (!editorInstance.document.getBody().getChild(0).getText()) {
do some action
}
It works fine for firefox, but in IE9 I get this error telling it's a null or undefined object (so IE doesnt check my condition).
so I tried:
var hasText = editorInstance.document.getBody().getChild(0).getText();
if (typeof hasText === 'undefined') {
do some action
}
The problem is that it still stops in the first line ( var hasText = edit... ), because the editorInstance.document.getBody().getChild(0).getText() returns null or undefined
EDIT
when I do editorInstance.document.getBody().getChild(0).getText(), I get all text entered in the textarea, but when there's no text entered (I check it to validate this field), this code returns nothing, this is why the hasText variable is not working the way I expected.
Any idea about how can I solve it?
You need to check for the presence of each variable and function result that you refer to.
var firstChild = editorInstance && editorInstance.document && editorInstance.document.getBody() && editorInstance.document.getBody().getChild(0);
if (!firstChild || firstChild.getText() === '') {
// do some action
}
&& is Javascript's logical AND operator. It’s very handy for cases like this, when you want to fetch an object's value, but the object itself might be null or undefined.
Consider the following statement:
var doc = editorInstance && editorInstance.document;
It means the same as
var doc;
if (editorInstance) {
doc = editorInstance.document;
} else {
doc = editorInstance;
}
but it's shorter. This statement will not error out if editorInstance is null.
function test() {
var editor_val1 = CKEDITOR.instances.id1.document.getBody().getChild(0).getText() ;
var editor_val2 = CKEDITOR.instances.id2.document.getBody().getChild(0).getText() ;
var editor_val3 = CKEDITOR.instances.id3.document.getBody().getChild(0).getText() ;
if ((editor_val1 == '') || (editor_val2 == '') || (editor_val3 == '')) {
alert('Editor value cannot be empty!') ;
return false ;
}
return true ;
}

Categories

Resources