Javascript option handling - javascript

What is a better/shorter way to write option handling in JavaScript. Instead of the following pattern?
if(typeof p_options.default_imageset !== "undefined") {
default_imageset = p_options.default_imageset;
} else {
default_imageset = 'mm';
}
Thanks.

You can use something like this:
var default_imageset = p_options.default_imageset || 'mm';
If p_options.default_imageset is truthy (not 0, null, false, '', etc.), the operator short-circuits.
Although usually I do it the other way around:
var value = supplied_value || default_value;

Related

Sequence Contains No elements? Impossible to handle error?

I have the next JavaScript:
var document = 0;
if ('#Model.Article.ListFiles.First()' != null) {
document = '#Model.Article.ListFiles.First()'; }
Article.ListFiles.First() has Count values '0' for this test and of course I receive error
"System.InvalidOperationException: 'Sequence contains no elements'"
but the problem is that I can't handle this error, I tried with try/catch but doesn't work. Also other operators (!= null, != '', != '0', != 0)
This solved my problem:
var document = '#Model.Article.ListFiles.FirstOrDefault()';
Thanks to all, special to asawyer!!!
Create a variable first, and check it aftetwards:
var a = '#Model.Article.ListFiles.First()';
var document = '';
if ( a !== null ) {
document = a;
}

How do I handle indexOf returning 'null' without using try/catch(err)?

I'm populating a table with data - using fixed-data-table, which is a React.js component. However, that isn't so important at this stage.
The table has a search box where the issue stems from.
First, here's the interesting part of the code.
for (var index = 0; index < size; index++) {
if (!filterBy || filterBy == undefined) {
filteredIndexes.push(index);
}
else {
var backendInfo = this._dataList[index];
var userListMap = hostInfo.userList;
var userListArr = Object.values(userListMap);
function checkUsers(){
for (var key in userListArr) {
if (userListArr.hasOwnProperty(key) && userListArr[key].text.toLowerCase().indexOf(filterBy) !== -1) {
return true;
}
}
return false;
}
if (backendInfo.firstName.indexOf(filterBy) !== -1 || backendInfo.lastName.toLowerCase().indexOf(filterBy) !== -1 || backendInfo.countryOrigin.toLowerCase().indexOf(filterBy) !== -1
|| backendInfo.userListMap.indexOf(filterBy) !== -1) {
filteredIndexes.push(index);
}
}
}
This is rendered and the last part is throwing errors if you input something in the table, and a column returns null from the user input.
The thing is, I can make the code work if I change the last part to ..
try {
if (backendInfo.firstName.indexOf(filterBy) !== -1 || backendInfo.lastName.toLowerCase().indexOf(filterBy) !== -1 || backendInfo.countryOrigin.toLowerCase().indexOf(filterBy) !== -1
|| backendInfo.userListMap.indexOf(filterBy) !== -1) {
filteredIndexes.push(index);
}
}
catch(err) {
console.log('Exception')
}
With the try/catch, it works 100% as intended and handles the indexOf returning null... But this can't be the way to properly handle it - I'm assuming this sort of exception handling is, well, supposed to be for rare exceptions, and shouldn't really be used on the front-end as much as the backend.
How do I handle indexOf returning null in the above Javascript code? It might return null in any of the sources columns that are being populated.
If a key cannot be found, JS will throw an error. Try-catch is a good way to fix these errors, but there is an alternative:
You could check if keys exist in an object prior to pushing a value into it.
var data = { };
var key = "test";
// your method works great
try {
var value = data.firstname.indexOf(key);
} catch (err) {}
// another method, I'd prefer the try/catch
var value = data.firstname ? data.firstname.indexOf(key) : undefined;
// test if the object is the type of object you are looking for
// this is in my opinion the best option.
if(data.firstname instanceof Array){
var value = data.firstname.indexOf(key);
}
// you can use the last option in your code like this:
var firstnameHasKey = data.firstname instanceof Array && ~data.firstname.indexOf(key);
var lastnameHasKey = data.lastname instanceof Array && ~data.lastname.indexOf(key);
if(firstnameHasKey || lastnameHasKey){
// logics
}
If you test the instanceof && indexOf, there will never be an error. If firstname is undefined, the indexOf will never be checked.
Ofcourse you can use this for other types:
var myDate = new Date();
myDate instanceof Date; // returns true
myDate instanceof Object; // returns true
myDate instanceof String; // returns false
MDN documentation

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 code check, if not undefined

Is this code good?
var wlocation = $(this).closest('.myclass').find('li a').attr('href');
if (wlocation.prop !== undefined) { window.location = wlocation; }
or should I do
var wlocation = $(this).closest('.myclass').find('li a').attr('href');
if (wlocation.prop !== "undefined") { window.location = wlocation; }
I like this:
if (wlocation !== undefined)
But if you prefer the second way wouldn't be as you posted. It would be:
if (typeof wlocation !== "undefined")
I generally like the shorthand version:
if (!!wlocation) { window.location = wlocation; }
$.fn.attr(attributeName) returns the attribute value as string, or undefined when the attribute is not present.
Since "", and undefined are both falsy (evaluates to false when coerced to boolean) values in JavaScript, in this case I would write the check as below:
if (wlocation) { ... }

Jasmine expect logic (expect A OR B)

I need to set the test to succeed if one of the two expectations is met:
expect(mySpy.mostRecentCall.args[0]).toEqual(jasmine.any(Number));
expect(mySpy.mostRecentCall.args[0]).toEqual(false);
I expected it to look like this:
expect(mySpy.mostRecentCall.args[0]).toEqual(jasmine.any(Number)).or.toEqual(false);
Is there anything I missed in the docs or do I have to write my own matcher?
Add multiple comparable strings into an array and then compare. Reverse the order of comparison.
expect(["New", "In Progress"]).toContain(Status);
This is an old question, but in case anyone is still looking I have another answer.
How about building the logical OR expression and just expecting that? Like this:
var argIsANumber = !isNaN(mySpy.mostRecentCall.args[0]);
var argIsBooleanFalse = (mySpy.mostRecentCall.args[0] === false);
expect( argIsANumber || argIsBooleanFalse ).toBe(true);
This way, you can explicitly test/expect the OR condition, and you just need to use Jasmine to test for a Boolean match/mismatch. Will work in Jasmine 1 or Jasmine 2 :)
Note: This solution contains syntax for versions prior to Jasmine v2.0.
For more information on custom matchers now, see: https://jasmine.github.io/2.0/custom_matcher.html
Matchers.js works with a single 'result modifier' only - not:
core/Spec.js:
jasmine.Spec.prototype.expect = function(actual) {
var positive = new (this.getMatchersClass_())(this.env, actual, this);
positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
return positive;
core/Matchers.js:
jasmine.Matchers = function(env, actual, spec, opt_isNot) {
...
this.isNot = opt_isNot || false;
}
...
jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
return function() {
...
if (this.isNot) {
result = !result;
}
}
}
So it looks like you indeed need to write your own matcher (from within a before or it bloc for correct this). For example:
this.addMatchers({
toBeAnyOf: function(expecteds) {
var result = false;
for (var i = 0, l = expecteds.length; i < l; i++) {
if (this.actual === expecteds[i]) {
result = true;
break;
}
}
return result;
}
});
You can take the comparison out of the expect statement to gain full use of comparison operators.
let expectResult = (typeof(await varA) == "number" || typeof(await varA) == "object" );
expect (expectResult).toBe(true);

Categories