handle undefined window in nodejs - javascript

I have a constant file which I share between my node backend and frontend (.ts file)
In backend inside the file I have done something like this
if (window) {
window.redirectPaths = {
// some code
}
} else {
// something
}
For NodeJS, Since window doesn't exist, I thought it will go to else but instead it is throwing the following error
if (window) {
^
ReferenceError: window is not defined
Any help in why is this happening and how can I solve this?

use typeof window !== "undefined"
if (typeof window !== "undefined") {
window.redirectPaths = {
// some code
}
} else {
//

you want to check the window type first before accessing it.
if (typeof window === 'undefined'){
// some code
} else {
window.redirectPaths = {
// some other code
}
}

You can check this way
if (typeof window !== 'undefined' && window){
window.redirectPaths = {
// some other code
}
} else {
// some code
}

In Node.js environment it is called global object. So you can write global instead of window

you could use try catch
try {
window.redirectPaths = {
// some code
}
} catch (err) {
// something else
}

Related

Passing the methods hide/show to another method

I am calling an object method in two ways in my code:
this.reveal.updateVisuals(i, 'show');
or
this.reveal.updateVisuals(i, 'hide');
and I am passing the hide and show condition as a string, to be later evaluated and used as a method. Please note the condition: if (effect === 'show/hide').
updateVisuals: function (time, effect) {
// Check if parameter exists and property can be read
if (this.breakpointsMap && typeof this.breakpointsMap[checkTime] !== "undefined") {
if (effect === 'show') {
// display the items that were fast forwarded
var k = this.breakpointsMap[checkTime].length;
while (k--) {
try {
this.breakpointsMap[checkTime][k].show();
} catch (err) {}
}
} else if (effect === 'hide') {
// display the items that were fast forwarded
var k = this.breakpointsMap[checkTime].length;
while (k--) {
try {
this.breakpointsMap[checkTime][k].hide();
} catch (err) {}
}
}
}
}
However the code seems duplicated and I was wondering if there is a way to pass hide or show as a method to the method and apply it on the array, when needed. I tried something like this:
this.reveal.updateVisuals(i).show
There are a lot of ways you can use to simplify this, here are a couple:
updateVisuals: function (time, effect) {
if (this.breakpointsMap && typeof this.breakpointsMap[checkTime] !== "undefined") {
this.breakpointsMap[checkTime].forEach(e => e[effect]());
}
}
Or returning the array:
updateVisuals: function (time, effect) {
if (this.breakpointsMap && typeof this.breakpointsMap[checkTime] !== "undefined") {
return this.breakpointsMap[checkTime];
}else{
return [];
}
}
this.reveal.updateVisuals(i).forEach(e => e.show());
You can access a method property by it's (string) name using [bracket] notation.
updateVisuals: function (time, effect) {
// Check if parameter exists and property can be read
if (this.breakpointsMap && typeof this.breakpointsMap[checkTime] !== "undefined") {
var k = this.breakpointsMap[checkTime].length;
while (k--) {
try {
this.breakpointsMap[checkTime][k][effect]();
} catch (err) {}
}
}
}
if you are using Es6, you can do:
function updateVisuals (time, effect) {
// Check if parameter exists and property can be read
if (this.breakpointsMap && typeof this.breakpointsMap[checkTime] !== "undefined") {
let execFn= (arrindex) => breakpointsMap[checkTime][arrindex].show();
if (effect === 'hide')
{
execFn = (arrindex) => breakpointsMap[checkTime][arrindex].hide();
}
// display the items that were fast forwarded
var k = this.breakpointsMap[checkTime].length;
while (k--) {
try {
execFn(k);
} catch (err) {}
}
}
}
I assume that var checkTime is global or in closure. If you are using version lower tan es6 you can use execFn= function (arrindex) {...}, a then bind this argument when calling method after.

How to check if function exist?

How to check if is function on jquery, but function is in another .js file?
validation.js:
if ($.isFunction('payment')) {
$('[data-numeric]').payment('restrictNumeric');
$('.cc-number').payment('formatCardNumber');
$('.cc-exp').payment('formatCardExpiry');
$('.cc-cvc').payment('formatCardCVC');
}
this is false because func payments is in the payments.js .
Try like this
if (typeof payment === "function")
{
// Do something
}
problem is solved. its works:
if ($.fn.payment) {
//do something
}
Try to check like as follows,
if (typeof payment !== 'undefined' && $.isFunction(payment)) {
$('[data-numeric]').payment('restrictNumeric');
$('.cc-number').payment('formatCardNumber');
$('.cc-exp').payment('formatCardExpiry');
$('.cc-cvc').payment('formatCardCVC');
}
You can check if a function exists using window
For example
var fn = window['NameOfTheFunction'];
if(typeof fn === 'function') {
doSomething();
}
If your function in payment.js is part of a self contained function, you need to set it to so the window object can "see" it by adding this in your self contained function:
window.NameOfTheFunction = NameOfTheFunction;

What are the best practices to make a plugin CJS, AMD, and script-tag friendly to also be CJS/AMD/script-tag ready?

I'm attempting to write a plugin for a library (MomentJS) that is usable almost everywhere. I'm planning on using it with RequireJS, so it has to be AMD friendly, but I'd also like to go ahead and make it usable by those who load it via script tags in the browser or in Node.
After poking around, I slapped this together:
(function() {
var hasModule = typeof module !== "undefined" && module.exports;
var MY_LIB_DEF = function (moment, global) {
if(typeof moment == "undefined") {
throw "Can't find moment";
}
var MY_LIB = {
//
//DEFINE PLUGIN
//
};
if(hasModule) {
module.exports = LIB
} else if(global) {
global.LIB = LIB;
} else {
return LIB;
}
};
if(hasModule) {
moment = require('moment');
}
if (typeof define === "function" && define.amd) {
define(["moment"], MY_LIB_DEF);
} else {
MY_LIB_DEF(moment, this);
}
})();
The bottom section of MY_LIB_DEF where I determine if I'm exporting for CJS, attatching to window, or returning for AMD seems a bit clunky as does my picking of which way to kick off (CJS and script loading would share the running of the defining function. But the "global" passed into it will never be used).
While the above works, I'm thinking that this problem has to have been solved already. I just can't seem to find any examples to follow.
Anyone aware of better practices for this?
After searching around, I found some good info here to help solve the problem. Still had to massage it a bit for my purpose, but it seems to be the solution.
(function(root, definition) {
"use strict";
var moment;
if (typeof module !== 'undefined' && module.exports) {
moment = require('moment');
module.exports = definition(moment);
} else if (typeof define === 'function' && define.amd){
define(['moment'], definition);
} else {
root['MY_LIB'] = definition(root.moment);
}
}(this, function(moment) {
if(typeof moment === "undefined") {
throw "Can't find moment";
}
return {
foo: function() {
console.log('bar');
}
};
}));

How to check for a JavaScript Object given it's name as a string?

I'm having trouble figuring out how I can take a string of an object name and check if that object actually exists.
What I'm trying to accomplish is have an array the defines the required objects for a particular JavaScript "module" to work, for instance:
var requiredImports = ['MyApp.Object1', 'MyApp.Object2'];
Then using requiredImports, I want to loop over them and check if the are defined. Without using the above array, I can do the following which is what I'm trying to accomplish:
if (MyApp.Object1 == undefined) {
alert('Missing MyApp.Object1');
}
But using the above, I'd have to hard code this for every module rather than making a generic method that I can just pass it an array of strings and have it effectively do the same check for me.
I tried doing this by just passing it the objects themselves such as:
var requiredImports = [MyApp.Object1, MyApp.Object2];
But that throws a JavaScript error when those objects do not exist, which is what I'm trying to catch.
var MyApp = {
Object1: {}
};
function exists(varName, scope) {
var parent = scope || window;
try {
varName.split('.').forEach(function (name) {
if (parent[name] === undefined) {
throw 'undefined';
}
parent = parent[name];
});
}
catch (ex) {
return false;
}
return true;
}
console.log(
exists('MyApp.Object1'), // true
exists('MyApp.Object2'), // false
exists('window'), // true
exists('document'), // true
exists('window.document') // true
);
// or
console.log(
['MyApp.Object1', 'MyApp.Object2', 'window', 'document', 'window.document'].filter(function (varName) {
return !exists(varName);
})
);
// => ["MyApp.Object2"]
Note: that forEach is ES5 and as such not implemented in some browsers. But if you'd go with this solution, there is a nice polyfill here.
You can check for definedness with
if ( typeof window['MyApp'] === 'undefined' ||
typeof window['MyApp']['Object1'] === 'undefined' )
{
alert('Missing MyApp.Object1');
}
and so on.
Assuming MyApp.Object1 is a global scope, window is the parent object and since that is the top level object, you don't need to prefix your global vars with it. So window.MyApp.Object1 is the same as MyApp.Object1 (again, assuming this is within global scope).
Also, in javascript, MyApp['Object1'] is the same as MyApp.Object1. So if we apply this principle to the main window object, you can check for window['MyApp'] or window['MyApp']['Object1'] and the key here is that you can replace 'MyApp' and 'Object1' with a variable.
Example:
/* check if a variable/object exists in the global scope) */
function checkIfExists(someVar) {
if (typeof(window[someVar]) == 'undefined')
return true;
return false;
}
var foo = 'bar';
alert(checkIfExists('foo'));
You can evaluate your custom expression in JavaScript. Consider the code below:
var MyApp = {
Object1: "foo",
Object2: "bar"
};
var IsExists = function(varName) {
return new Function('return typeof(' + varName + ') === "undefined" ? false : true;')();
};
USAGE
var requiredImports = ['MyApp.Object1', 'MyApp.Object2'];
for (var i = 0; i < requiredImports.length; i++)
{
alert(requiredImports[i] + ": " + IsExists(requiredImports[i]))
}
You only get error for first level (MyApp in your example). I assume you have only a few first-level requires, so check them manually by window[x] which does not throw:
var requiredTopLevel = ['MyApp'];
for (var i = 0; i < requiredTopLevel.length; ++i) {
if ("undefined" === typeof window[requiredTopLevel[i]]) {
// problem with requiredTopLevel[i]
}
}
and then, to check nested requires (if top-level is present) you can use the values without fear. For example this will work:
var requiredNested = { 'Object1':MyApp.Object1, 'Object2':Myapp.Object2 };
for (var name in requiredNested) {
if ("undefined" === typeof requiredNested[name]) {
// problem with name
}
}

Most elegant way to check sessionStorage support?

I have a cookie checker function, which storage a value variable in the var 'cookie1'.
And a sessionStorage storage cookie.
if (cookie1 == '9oz' | sessionStorage.getItem('sessionstoragecookie1') == '9oz')
{
// execute code 1
}
else
{
// execute code 2
}
But sessionStorage is not supported in IE6 and IE7. So it throws an error and breaks the entire script. I could do something like this, but this is absolutely not elegant. What is the most elegant way to work this around?
if (cookie1 == '9oz')
{
// execute code 1
}
else
{
if (typeof(sessionStorage) !='undefined')
{
if (sessionStorage.getItem('sessionstoragecookie1') == '9oz')
{
// execute code 1
}
else
{
// execute code 2
}
}
else
{
// execute code 2
}
}
if (cookie1 === '9oz' || (window.sessionStorage && window.sessionStorage.getItem('sessionstoragecookie1') === '9oz')) {
// you've got a 9oz reference
} else {
// you haven't :(
}
if(typeof(sessionStorage) == 'undefined')
{
sessionStorage = {
getItem: function(){},
setItem: function(){},
clear: function(){},
removeItem: function(){}
};
}
And now use as usual. It will always return NULL
But I would consider this script
http://code.google.com/p/sessionstorage/
This will enable sessionStorage in every browser.
I would use try/catch to check if the browser supports sessionStorage.
function isSessionStorageSupported() {
try {
var storage = window.sessionStorage;
storage.setItem('test', 'test');
storage.removeItem('test');
return true;
} catch (e) {
return false;
}
}
Use the function like this:
if (isSessionStorageSupported()) {
// do something with it
} else {
// have a fallback code here
}
function checkSessionStorage()
{
return window.sessionStorage;
}
If it is undefined then sessionStorage is not supported.
You can try something like this:
What it does is that if a browser doesn't support sessionStorage, it clears the session.
try {
sessionStorage.setItem('name','value');
}
catch(e){
if(e.code == 22){
sessionStorage.clear(); }
}
I know I'm a little late to the party, but I have a few useful functions I cooked up and threw into a file named 'manage_storage.js'. I hope they are as useful to you guys, as they have served me well.
Here is my code:
/* Conditional Function checks a web browser for 'session storage' support. [BEGIN] */
if (typeof isSessStorageAllowed !== 'function')
{
function isSessStorageAllowed()
{
if (!!window.sessionStorage && typeof sessionStorage.getItem === 'function' && typeof sessionStorage.setItem === 'function' && typeof sessionStorage.removeItem === 'function')
{
try
{
var cur_dt = new Date();
var cur_tm = cur_dt.getTime();
var ss_test_itm_key = 'ss_test_itm_' + String(cur_tm);
var ss_test_val = 'ss_test_val_' + String(cur_tm);
sessionStorage.setItem(ss_test_itm_key, String(ss_test_val));
if (sessionStorage.getItem(ss_test_itm_key) == String(ss_test_val))
{
return true;
}
else
{
return false;
};
sessionStorage.removeItem(ss_test_itm_key);
}
catch (exception)
{
return false;
};
}
else
{
return false;
};
};
};
/* Conditional Function checks a web browser for 'session storage' support. [END] */
/* Conditional Function checks a web browser for 'local storage' support. [BEGIN] */
if (typeof isLclStorageAllowed !== 'function')
{
function isLclStorageAllowed()
{
if (!!window.localStorage && typeof localStorage.getItem === 'function' && typeof localStorage.setItem === 'function' && typeof localStorage.removeItem === 'function')
{
try
{
var cur_dt = new Date();
var cur_tm = cur_dt.getTime();
var ls_test_itm_key = 'ls_test_itm_' + String(cur_tm);
var ls_test_val = 'ls_test_val_' + String(cur_tm);
localStorage.setItem(ls_test_itm_key, String(ls_test_val));
if (localStorage.getItem(ls_test_itm_key) == String(ls_test_val))
{
return true;
}
else
{
return false;
};
localStorage.removeItem(ls_test_itm_key);
}
catch (exception)
{
return false;
};
}
else
{
return false;
};
};
};
/* Conditional Function checks a web browser for 'local storage' support. [END] */
/* Conditional Function checks a web browser for 'web storage' support. [BEGIN] */
/* Prerequisites: 'isSessStorageAllowed()', 'isLclStorageAllowed()' */
if (typeof isWebStorageAllowed !== 'function')
{
function isWebStorageAllowed()
{
if (isSessStorageAllowed() === true && isLclStorageAllowed() === true)
{
return true;
}
else
{
return false;
};
};
};
/* Conditional Function checks a web browser for 'web storage' support. [END] */

Categories