reading optional attributes from optional setting in javascript - javascript

What is the most efficient way of reading optional attributes in an optional setting argument. I'm using something like:
f = func(var1, optionalsettings) {
var2 = (optionalsettings === undefined ? 0
: (optionalsettings['var2'] == null ? 0 : optionalsettings['var2']));
};
But I've the feeling it can be done more efficiently, either in javascript or in jquery.

You could do:
var var2 = (optionalsettings && optionalsettings['var2']) || 0;
First you check is optionalsettings exists. If it does, you try to return optionalsettings['var2']. If that fails, you fall back on the default value.

also possible jquery's extend:
function myTest(arg1, arg2, optionalsettings) {
var settings = $.extend( {
opt1 : val1
, opt2 : val2}, optionalsettings || {})
...

Related

JavaScript with coffescript syntax- if condition : optimize if statement structure

I have a function and I'm testing 4 variables, I want to optimize the structure of my if statement test, can some one help ? :
$scope.filterActivated = ->
if $scope.postParams.options.scopes.report.from || $scope.postParams.options.scopes.report.to || $scope.postParams.options.template_id || $scope.displayOptions.query.length > 0
return true
else
return false
you can remove true/false and optimize it a little bit like this:
$scope.filterActivated = ->
options = $scope.postParams.options
options.scopes.report.from or options.scopes.report.to or options.template_id or $scope.displayOptions.query.length > 0
Edit: JS for you:
$scope.filterActivated = () => {
let options = $scope.postParams.options;
return options.scopes.report.from || options.scopes.report.to || options.template_id || $scope.displayOptions.query.length > 0;
};
Not sure what you mean by optimizing, but a shorthand of that could be:
$scope.filterActivated = ->
$scope.postParams.options.scopes.report.from
|| $scope.postParams.options.scopes.report.to
|| $scope.postParams.options.template_id
|| $scope.displayOptions.query.length;
Edit:
Initially, I used the ternary syntax, but that's not supported by CoffeeScript. For reference Ternary operation in CoffeeScript
Edit 2:
Reduced it a bit more, #user633183 suggested using Boolean but I think this gives the same result.

Setting a Javascript if statement with 2 requirements to one line

var status = result.locations[index].status;
var operator = result.locations[index].operator;
var original = result.locations[index].original;
var produced = result.locations[index].produced;
var href = result.locations[index].more;
I have the above which each need to be an if statement to check if there is content and my output is the below code.
if (result.locations[index] && result.locations[index].status){
var status = result.locations[index].status;
} else {
var status = '';
}
I would need to reproduce this per line from the code at the top of the post. What would be the best method to simplify each down to keep the code neater and not produce 5 lines of if statement when 1 or 2 would do.
var status = (result.locations[index] && result.locations[index].status ? result.locations[index].status : '');
Not sure why you want to, but:
var status = (result.locations[index] && result.locations[index].status) ? result.locations[index].status : ""
Your problem is trying to access a property of a "deep" javascript object using its path.
This is a common question :
Javascript: Get deep value from object by passing path to it as string
Accessing nested JavaScript objects with string key
There is no built-in way to do this in javascript.
There are plenty of libraries to do that, for example, with selectn, this would become something like (I have not tested it, so I don't know if the index part will work, but you get the idea) :
var status = selectn("locations." + index + ".status", result) || ''
If the structure of your objects is always the one above (that is, the property is just at one level of depth), and you're not expecting 'falsy', you could simply write the 'test' function yourself :
function safeGet(instance, propertyName, defaultValue) {
// As pointed by AlexK, this will not work
// if instance[propertyName] can be anything Falsy ("", 0, etc...)
// If it's possible, get a library that will do
// the full series of insane checks for you ;)
if (instance && instance[propertyName)) {
return instance[propertyName];
} else {
return defaultValue;
}
}
var location = result.locations[index]; // Potentially undefined, but safeGet will deal with it
var status = safeGet(location, "status", "");
var operator = safeGet(location, "operator", "DEFAULT_OPERATOR");
...
var status = result.locations[index] && result.locations[index].status || '';
However, better maje sure before, if result.locations[index] exists... else do whatever is to be done in your code..

Check exactly one boolean option set

Well, this is kind of hacky:
function b2n(boo) {
return boo ? 1 : 0;
}
if(b2n(opt1) + b2n(opt2) + b2n(opt3) !== 1) {
throw new Error("Exactly one option must be set");
}
Is there a better way to do this in Javascript? Using any of
more intelligent boolean/number handling
sneaky array or functional operations
And so forth. Javascript and Node solutions welcome.
In my actual problem, the options are coming from the Node module commander, so I'm not dealing with true boolean, just truthy and falsy things. There may be a commander-solution too.
Assuming you had an array of options, you could do:
if(opts.filter(Boolean).length !== 1) {}
It seems to me though that you ought to have one variable with three possible states instead...
var opt = 'a'; // (or 'b', or 'c')
You can do this :
if ( !!opt1 + !!opt2 + !!opt3 !== 1 ) {
It works because
!! makes a boolean from any value (true if the objects evaluates as true in if(value))
when adding booleans you get 1 for true and 0 for false.
You mentioned in your comment that this is coming from a commander options object.
You can do this more elegantly using Lodash:
if (_(options).values().compact().size() === 1)
If you only want to count a subset of the options, you can insert
.pick('a', 'b', 'c')
if ([opt1, opt2, opt3].reduce(function(x, y) { return x + !!y }, 0) == 1) {
// exactly one
};
ECMAScript 5 reduce function.
I think you are being too clever, what's wrong with:
var optionsSelected = 0;
if( opt1 ) optionsSelected++;
if( opt2 ) optionsSelected++;
if( opt3 ) optionsSelected++;
if( optionsSelected !== 1 ) {
throw new Error("Exactly one option must be set");
}
Of course I can play the clever game too:
if( opts.filter(Boolean).length !== 1 ) {
throw new Error("Exactly one option must be set");
}
#spudly is on the right track, but it could be a little more compact:
if( [opt1,opt2,opt3].filter(function(x){return x}).length!==1 ) {
throw new Error("Exactly one option must be set");
}
See ES5's filter method for more information.

Javascript setting variable to result or nothing

See javascript comments
var SearchResult = {
googleApiKey: "",
googleUrl: "https://www.googleapis.com/shopping/search/v1/public/products?key={key}&country={country}&q={query}&alt=atom",
country: "UK"
Query: function( args )
{
// Is there a way to do this in a less messy way?
args.googleApiKey ? : this.googleApiKey = args.googleApiKey : null;
args.country? : this.country = args.country: null;
}
}
Basically, if someone supplies a new value for my object properties, I want it to set it, otherwise just continue using the default values supplied.
I'm aware of bitwise operators being good for option selecting but I don't know how I would port that into javascript?
args.googleApiKey = args.googleApiKey || this.googleApiKey;
args.country = args.country || this.country;
Not sure I understood your question;
In JavaScript you can use the following:
// thingYouWantToSet = possiblyUndefinedValue || defaultValue;
this.googleApiKey = args.googleApiKey || '';
The caveat to using this is that if the first value is a zero or empty string, you will end up using the default value, which may not be what you intend. e.g.
var example = '';
var result = example || 'default';
Although example is set, you will end up with the 'default' string. If this causes issues for you, switch to:
(typeof args.googleApiKey === 'undefined')
? this.googleApiKey = 'default'
: this.googleApiKey = args.googleApiKey;
You could make this cleaner using a helper function if you are repeating yourself a lot.
var mergedSetting = function (setting, default) {
return (typeof setting === 'undefined') ? default : setting;
}
this.googleApiKey = mergedSetting(args.googleApiKey, 'default value');

jquery/javascript missing ) after formal parameters

Hi there I have this code:
function getFullnameDetails(mainHeight,upperstyle,type=''){
setTimeout(function(){fullnameCenter(mainHeight,upperstyle,type='')},2000);
}
function fullnameCenter(mainHeight,upperstyle,type=''){
var distOfMainAndUpper = mainHeight - upperstyle;
var mainHalfHeight = mainHeight/2;
var imageHeight = jQuery("img[rel='fullname']").height(); //there is a delay
var imageHalfHeight = imageHeight/2;
var fromImageTopToMainHalf = mainHalfHeight - imageHeight;
var position = imageHalfHeight+fromImageTopToMainHalf-distOfMainAndUpper;
if(type == 'big'){ jQuery("#temp .test1").css("bottom",position+"px"); }
else { jQuery(".test1").css("bottom",position+"px"); }
}
It says that I'm missing ) after formal parameters.
This happens on this line:
function getFullnameDetails(mainHeight,upperstyle,type=''){ //IT HAPPENS HERE! :)
setTimeout(function(){fullnameCenter(mainHeight,upperstyle,type='')},2000);
}
What am I doing wrong here.
Thanks in advance for the help :)
Javascript does not support default function parameter values.
You can do things like this (but be wary of unintended 'falsey' values):
function getFullnameDetails(mainHeight,upperstyle,type){
type = type || ''; // if type is 'falsey' (null, undefined, empty string) assign ''
//...
}
As other answers have pointed out, JavaScript doesn't support default values in the function parameters. However, as also pointed out in the other solutions, using an inline || won't work when falsey values are passed (eg null, 0, '', NaN, false). A better solution is to check to see if the argument is undefined:
type = typeof(type) !== 'undefined' ? type : '';
or, more generally:
argument_name = typeof(argument_name) !== 'undefined' ? argument_name : default_value;
Of course, this means that passing undefined to a function will mean that the default value is used instead - but that should be pretty uncommon.
Are you trying to use like a default parameter or something?
type=''
That is not valid -- you can't have an equal sign in the parameter list of a function like that.

Categories