Setting variable with more than two conditions in JavaScript - javascript

First time dealing with this so please bare with me.
I inherited a web application that handles three different environments but shares the same code base. Essentially, it's three different web applications rolled into one - with minor to major adjustments on each environment.
I'm launching the site and the CSS and JS paths linked need to change, to take into account a new domain folder.
I found a variable called 'DOMAINBASE', and some variables above it - please see the code below:
export const isEnvironmentBFE:boolean = checkEnvironment(DEPLOY_ENV.BFE);
export const isEnvironmentTCAT:boolean = checkEnvironment(DEPLOY_ENV.TCAT);
export const isEnvironmentBFERENTAL:boolean = checkEnvironment(DEPLOY_ENV.BFERENTAL);
export const DOMAINBASE = checkEnvironment(DEPLOY_ENV.BFE)
? "https://subdomain.domain1.ca"
: "https://subdomain.domain2.com";
I want to add another condition, in other words another URL to DOMAINBASE, where there is currently only two.
I've tried adding the following condition but does not work:
export const DOMAINBASE = checkEnvironment(DEPLOY_ENV.BFE)
? "https://subdomain.domain1.ca"
: checkEnvironment(DEPLOY_ENV.BFERENTAL) // <-- when new environment is launched
? "https://subdomain.domain1.ca/new-folder" // <-- make it so it uses this structure
: "https://subdomain.domain2.com";
How do I properly add a third condition to this JavaScript variable?

Perhaps try it without the 'export'?
This is working for me when i try from the console
const DOMAINBASE = 5<6
? "https://subdomain.domain1.ca"
: 6<7
? "https://subdomain.domain1.ca/new-folder"
: "https://subdomain.domain2.com";

Related

Nodejs and Expressjs: Constants in global variable

Defined in: util/constant.js
module.exports = {
userTypeAdmin: 0,
userTypeUser: 1
};
Required only once in: app.js
...
global.constant = require('./util/constant');
...
Used many times
In: route/index.js
console.log(constant.userTypeAdmin); // Show 0
In: route/user.js
console.log(constant.userTypeUser); // Show 1
Question:
I must removed of app.js: global.constant = require('./util/constant');
and add: const constant = require('../util/constant');
in route/index.js and route/user.js ?
Or that's ok how I am it making?
1. const constant = require('../util/constant');
2. global.constant = require('./util/constant');
Only difference in these,
statement 1 ask you to import the constant package wherever you want to use it.
statement 2 make available constant package globally.so,you can access it without import.
With statement 2,if you modified any properties within constant,it will reflect throughout the application.
So,make sure,you are using global only when you want to share something across the application.
If you want to share the data globally,and don't want this should be change,then delcare each primitive variable with const keyword.In this case,making object const will not help you.
In either case you can exclude it.

How can an extension expand configuration variables in VSCode?

I tried to write an extension for vscode, the extension needs to read pasteImage.parth variable from ./vscode/settings.json file
{
"pasteImage.path": "${workspaceRoot}/assets/images"
}
I tried to use vscode.workspace.getConfiguration() function to get the variable like this:
let folderPathFromConfig = vscode.workspace.getConfiguration('pasteImage')['path'];
But it got ${workspaceRoot}/assets/images, I want ${workspaceRoot} to expand to the real path of the workspace root, what should I do?
Thanks for any hint!
There doesn't seem to be a service for it, you'd have to extend the AbstractVariableResolverService similarly to the debug host to do this.
Unfortunately you cannot import these things from within your extension.
The actual implementation is quite straightforward but I do wonder what they thought when they decided against this.
IProcessEnvironment is just a stupid interface for the built-in process.env prop.
According to the vscode extensibility documentation you can use
let workspaceRoot = vscode.workspace.workspaceFolders[0];
to get the root WorkspaceFolder. You can get the absolute path of a WorkspaceFolder by using its Uri:
let workspaceRootPath = workspaceRoot.uri.path;
Then you just replace the "${workspaceRoot}" sub string of the folderPathFromConfig.
To conclude:
let folderPathFromConfig = vscode.workspace.getConfiguration('pasteImage')['path'];
if (vscode.workspace.workspaceFolders !== undefined) { // is undefined if no folder is opened
let workspaceRoot = vscode.workspace.workspaceFolders[0];
folderPathFromConfig = folderPathFromConfig.replace('${workspaceRoot}', workspaceRoot.uri.path);
}

Node define unique variable that I need to use across the modules

Currently I am just passing my fileNamePrefix like that:
let shortid = require('shortid');
let fileNamePrefix = shortid.generate();
module1.run(fileNamePrefix); //generating a file based on `fileNamePrefix` `xxxxx.f1.json`
module2.run(fileNamePrefix); //generating a file based on `fileNamePrefix` `xxxxx.f2.json`
module3.run(fileNamePrefix); //generating a file based on `fileNamePrefix` `xxxxx.f3.js
Which I think in not quite right, I might need to pass more things to my modules later on, so I want to avoid to pass that as function params.
What is the best way to approach that in nodejs?
Will global object like global.fileNamePrefix = shortid.generate(); will do in that case or would you approach that different? I just read that global is not good...
You can use either singleton approach or approach suggested by #Сергей Тертичный
Singleton :
//shortid.js
var fileSingleTon = module.exports = {
fileNamePrefix: null,
getFileNamePrefix: function() {
return fileSingleTon.fileNamePrefix || fileSingleTon.generate()
},
generate: function() {
console.log('generating..');
return fileSingleTon.fileNamePrefix = 'your_file_prefix';
}
}
//module1.js
var fileNamePrefix = require('./shortid').getFileNamePrefix();
//do stuff for module1
//module2/js
var fileNamePrefix = require('./shortid').getFileNamePrefix();
//do stuff for module1
and so on..
Even now you are calling require('./shortid').getFileNamePrefix(); multiple times, generate function is getting called only once.
Node Caching approach :
Consider you have shortid.js as following :
// A: block of code to do some manipulations
// B : module.exports = manipulation result.
So basically in node js "modules" core module which is responsible for giving us module.export functionality executes whatever is here above export(in abode example the part A) only for the first time and caches it even if you have required in in multiple other files. However, it only executes the functions or block of code in every require which is inside export. So you can use this approach where your A block will have login to generate fileNamePrefix and then B just returns it.
Just create module like that:
// unicname.js
let shortid = require('shortid');
let fileName = shortid.generate();
module.exports = {fname: fileName};
//module1.js
const {fname} = require('./unicname.js');
....
Since the node.js caching the modules the value will be calculated only one time so you can get same value in all your modules.

What are the global all-caps variables defined in the example Todos app?

I am reading through the Meteor example app "todos" for learning purposes.
They use some all caps var and store them in Session.
It's defined at the first line:
var EDITING_KEY = 'EDITING_TODO_ID';
And used many times. For example:
Template.todosItem.helpers({
//...
editingClass: function() {
return Session.equals(EDITING_KEY, this._id) && 'editing';
}
});
Template.todosItem.events({
'blur input[type=text]': function(event) {
if (Session.equals(EDITING_KEY, this._id))
Session.set(EDITING_KEY, null);
},
//...
});
What is it and what makes it special?
EDITING_KEY is a file-scoped "constant" defined in todos-item.js used to reference the currently edited item minimongo _id in the global reactive persistent client-side dictionary Session.
It is used to avoid having to write the same string again and again everywhere, in that case 'EDITING_TODO_ID'. Writing it everywhere can lead to dumb bugs caused by typos like your templates not updating because you wrote 'EDITNG' instead of 'EDITING'.
Since Session simply needs a string as first parameter, these two lines do the very same thing :
Session.get(EDITING_KEY)
Session.get('EDITING_TODO_ID')
The example project uses this multiple times to avoid bugs and make auto-completion nicer.
You can see some more examples in other files, such as at the top of app-body.js :
var MENU_KEY = 'menuOpen';
Session.setDefault(MENU_KEY, false);
var USER_MENU_KEY = 'userMenuOpen';
Session.setDefault(USER_MENU_KEY, false);
var SHOW_CONNECTION_ISSUE_KEY = 'showConnectionIssue';
Session.setDefault(SHOW_CONNECTION_ISSUE_KEY, false);
You could go further and define those in a global key registry that would make sure there is no duplicated key, for example with an underlying Set. That could be a fun thing to do to train.
Since Meteor now supports ES2015 this should be rewritten to const EDITING_KEY = 'EDITING_TODO_ID' to avoid overwriting it by accident.
This appears just to be a variable that tracks what to-do is currently being edited. There's nothing special about it being in all-caps.

node.js and browser code reuse: importing constants into modules

I have some constants in JavaScript that I'd like to reuse in several files while saving typing, reducing bugs from mistyping, keeping runtime performance high, and being useful on either the node.js server scripts or on the client web browser scripts.
example:
const cAPPLE = 17;
const cPEAR = 23;
const cGRAPE = 38;
...(some later js file)...
for...if (deliciousness[i][cAPPLE] > 45) ...
Here are some things I could do:
copy/paste const list to top of each file where used. Oh, Yuck. I'd rather not. This is compatible with keeping the constant names short and simple. It violates DRY and invites all sorts of awful bugs if anything in the list changes.
constant list ---> const.js
on browser, this is FINE ... script gets fed in by the html file and works fine.
but on node.js, the require mechanism changes the constant names, interfering with code reuse and requiring more typing, because of how require works....
AFAIK This doesn't work, by design, in node.js, for any const.js without using globals:
require('./const.js');
for...if...deliciousness[i][cAPPLE] > 45 ...;
This is the node.js way:
(... const.js ....)
exports.APPLE = 17;
(... dependency.js ... )
var C = require('./const.js');
for...if...deliciousness[i][C.APPLE] > 45.....
so I would either have to have two files of constants, one for the node.js requires and one for the browser, or I have to go with something further down the list...
3 make the constants properties of an object to be imported ... still needs two files... since the node.js way of importing doesn't match the browser. Also makes the names longer and probably takes a little more time to do the lookups which as I've hinted may occur in loops.
4 External constant list, internal adapter.... read the external constants, however stored, into internal structure in each file instead of trying to use the external list directly
const.js
exports.cAPPLE = 17
browser.js
const cAPPLE = exports.cAPPLE;
...code requiring cAPPLE...
node.js
CONST = require(./const.js)
const cAPPLE = CONST.cAPPLE;
...code requiring cAPPLE...
This requires a one-time-hit per file to write the code to extract the constants back out, and so would duplicate a bunch of code over and over in a slightly more evolved cut and paste.
It does allows the code requiring cAPPLE to continue to work based on use of short named constants
Are there any other solutions, perhaps a more experienced JavaScripter might know, that I might be overlooking?
module.exports = Object.create({},{
"foo": { value:"bar", writable:false, enumerable:true }
});
Properties are not writable. Works in strict mode unlike "const".
I would just make them global keys:
...(module consts.js)...
global.APPLE = 17;
global.PEAR = 23;
global.GRAPE = 38;
...(some later js file)...
var C = require('./const.js');
for (var i = 0; i < something.length; i++) {
if (deliciousness[i][global.APPLE] > 45) { blah(); }
}
They wouldn't be enforced constants, but if you stick to the ALL_CAPS naming convention for constants it should be apparent that they shouldn't be altered. And you should be able to reuse the same file for the browser if you include it and use it like so:
var global = {};
<script src="const.js"></script>
<script>
if (someVar > global.GRAPE) { doStuff(); }
</script>
You can make an object unwritable using Object.freeze .
var configs={
ENVIRONMENT:"development",
BUILDPATH:"./buildFiles/",
}
Object.freeze(configs);
module.exports=configs;
Than you can use it as constant
var config=require('config');
// config.BUILDPATH will act as constant and will be not writable.

Categories