JavaScript Error in Pentaho - Cannot call method "toUpperCase" of null - javascript

// Sets all the letters as uppercase
var str = ae_a_asset_e$manufacture_code.toUpperCase();
var str2 = ae_a_asset_e$serial_no.toUpperCase();
var str3 = ae_a_asset_e$manu_part_number.toUpperCase();
var str4 = ae_a_asset_e$region_code.toUpperCase();
var str5 = ae_a_asset_e$fac_id.toUpperCase();
Any idea how to fix this? I would think there would have to be a way to say if value = null then don't worry about it.

First you have to think whether it is correct that some values are null or not, such as ae_a_asset_e$manufacture_code.
If they can be null you can access them in a safe way like this (extend this code to all other vars as required):
var str = ae_a_asset_e$manufacture_code ? ae_a_asset_e$manufacture_code.toUpperCase() : "";
If they cannot be null then, your should check your data integrity first and then run this script (assuming they are never null).

Related

Looking for the easiest way to extract an unknown substring from within a string. (terms separated by slashes)

The initial string:
initString = '/digital/collection/music/bunch/of/other/stuff'
What I want: music
Specifically, I want any term (will never include slashes) that would come between collection/ and /bunch
How I'm going about it:
if(initString.includes('/digital/collection/')){
let slicedString = initString.slice(19); //results in 'music/bunch/of/other/stuff'
let indexOfSlash = slicedString.indexOf('/'); //results, in this case, to 5
let desiredString = slicedString.slice(0, indexOfSlash); //results in 'music'
}
Question:
How the heck do I accomplish this in javascript in a more elegant way?
I looked for something like an endIndexOf() that would replace my hardcoded .slice(19)
lastIndexOf() isn't what I'm looking for, because I want the index at the end of the first instance of my substring /digital/collection/
I'm looking to keep the number of lines down, and I couldn't find anything like a .getStringBetween('beginCutoff, endCutoff')
Thank you in advance!
your title says "index" but your example shows you wanting to return a string. If, in fact, you are wanting to return the string, try this:
if(initString.includes('/digital/collection/')) {
var components = initString.split('/');
return components[3];
}
If the path is always the same, and the field you want is the after the third /, then you can use split.
var initString = '/digital/collection/music/bunch/of/other/stuff';
var collection = initString.split("/")[2]; // third index
In the real world, you will want to check if the index exists first before using it.
var collections = initString.split("/");
var collection = "";
if (collections.length > 2) {
collection = collections[2];
}
You can use const desiredString = initString.slice(19, 24); if its always music you are looking for.
If you need to find the next path param that comes after '/digital/collection/' regardless where '/digital/collection/' lies in the path
first use split to get an path array
then use find to return the element whose 2 prior elements are digital and collection respectively
const initString = '/digital/collection/music/bunch/of/other/stuff'
const pathArray = initString.split('/')
const path = pathArray.length >= 3
? pathArray.find((elm, index)=> pathArray[index-2] === 'digital' && pathArray[index-1] === 'collection')
: 'path is too short'
console.log(path)
Think about this logically: the "end index" is just the "start index" plus the length of the substring, right? So... do that :)
const sub = '/digital/collection/';
const startIndex = initString.indexOf(sub);
if (startIndex >= 0) {
let desiredString = initString.substring(startIndex + sub.length);
}
That'll give you from the end of the substring to the end of the full string; you can always split at / and take index 0 to get just the first directory name form what remains.
You can also use regular expression for the purpose.
const initString = '/digital/collection/music/bunch/of/other/stuff';
const result = initString.match(/\/digital\/collection\/([a-zA-Z]+)\//)[1];
console.log(result);
The console output is:
music
If you know the initial string, and you have the part before the string you seek, then the following snippet returns you the string you seek. You need not calculate indices, or anything like that.
// getting the last index of searchString
// we should get: music
const initString = '/digital/collection/music/bunch/of/other/stuff'
const firstPart = '/digital/collection/'
const lastIndexOf = (s1, s2) => {
return s1.replace(s2, '').split('/')[0]
}
console.log(lastIndexOf(initString, firstPart))

Javascript splitting string using only last splitting parameter

An example of what im trying to get:
String1 - 'string.co.uk' - would return 'string' and 'co.uk'
String2 - 'random.words.string.co.uk' - would return 'string` and 'co.uk'
I currently have this:
var split= [];
var tld_part = domain_name.split(".");
var sld_parts = domain_name.split(".")[0];
tld_part = tld_part.slice(1, tld_part.length);
split.push(sld_parts);
split.push(tld_part.join("."));
With my current code, it takes the split parameter from the beginning, i want to reverse it if possible. With my current code it does this:
String1 - 'string.co.uk' - returns 'string' and 'co.uk'
String2 - 'random.words.string.co.uk' - would return 'random` and 'words.string.co.uk'
Any suggestions?
To expand upon elclanrs comment:
function getParts(str) {
var temp = str.split('.').slice(-3) // grabs the last 3 elements
return {
tld_parts : [temp[1],temp[2]].join("."),
sld_parts : temp[0]
}
}
getParts("foo.bar.baz.co.uk") would return { tld_parts : "co.uk", sld_parts : "baz" }
and
getParts("i.got.99.terms.but.a.bit.aint.one.co.uk") would return { tld_parts : "co.uk", sld_parts : "one" }
try this
var str='string.co.uk'//or 'random.words.string.co.uk'
var part = str.split('.');
var result = part[part.length - 1].toString() + '.' + part[part.length - 1].toString();
alert(result);
One way that comes to mind is the following
var tld_part = domain_name.split(".");
var name = tld_part[tld_part.length - 2];
var tld = tld_part[tld_part.length - 1] +"."+ tld_part[tld_part.length];
Depending on your use case, peforming direct splits might not be a good idea — for example, how would the above code handle .com or even just localhost? In this respect I would go down the RegExp route:
function stripSubdomains( str ){
var regs; return (regs = /([^.]+)(\.co)?(\.[^.]+)$/i.exec( str ))
? regs[1] + (regs[2]||'') + regs[3]
: str
;
};
Before the Regular Expression Police attack reprimand me for not being specific enough, a disclaimer:
The above can be tightened as a check against domain names by rather than checking for ^., to check for the specific characters allowed in a domain at that point. However, my own personal perspective on matters like these is to be more open at the point of capture, and be tougher from a filtering point at a later date... This allows you to keep an eye on what people might be trying, because you can never be 100% certain your validation isn't blocking valid requests — unless you have an army of user testers at your disposal. At the end of the day, it all depends on where this code is being used, so the above is an illustrated example only.

err variable space is undefined why?

I run next code and I miss somthing, for me it seem OK :
window.onload = TitleFieldInit;
function TitleFieldInit() {
var str = document.cookie.split("=")[1];
var space = str.split("=")[1];
space = space.split(";")[0];
alert(space);
// while( space.indexOf('%20' )+1) space = space.replace(/%20/,' ');
if (document.cookie != "") {
document.getElementById("TitleField").innerHTML = "Your Title is : " + space;
}
}​
and I got err in FireFox rror"space is undefined" why ?
In chrome "Uncaught TypeError:Cannot call method'split' of Undefined"
Thx for helping.
This code will never work for any input.
str is a already part of result of split by =, i.e. it contains no = symbols.
Then you split that result again by =, which of course will return you one-element array and str.split("=")[1] will always be undefined.
Looks like you're trying to read cookie value... but second .split("=") is not needed at all.
Ah, and you got different results in different browsers, cause they contain different data in their cookies.
PS: Instead of while( space.indexOf('%20' )+1) space = space.replace(/%20/,' '); you may write space = space.replace(/%20/g,' '); to replace all of them at once.

Javascript RegEx Mysteries (for a poor C programmer)

This is clearly a RTFM issue, but after I did so repeatedly I just can't get the damn thing to work so there are times when asking for help makes sense:
var text = "KEY:01 VAL:1.10,KEY:02 VAL:2.20,KEY:03 VAL:3.30";
var pattern = '/KEY:(\S+) VAL:([^,]+)/g';
//var pattern = '/KEY:(\S+) VAL:(.?+)(?:(?=,KEY:)|$)/g';
//var pattern = '/KEY:(\S+) VAL:(.+)$/g';
//pattern.compile(pattern);
var kv = null;
var row = 0, col = 0;
while((kv = pattern.exec(text) != null))
{
row = kv[1].charAt(0) - '0';
col = kv[1].charAt(1) - '0';
e = document.getElementById('live').rows[row].cells;
e[col].innerHTML = kv[2].slice(0, kv[2].indexOf(","));
}
kv[1] is supposed to give "01"
kv[2] is supposed to give "1.10"
...and of course kv[] should list all the values of 'text'
to fill the table called 'live'.
But I can't get to have pattern.exec() succeed in doing that.
Where is the glitch?
First, the delimiters for the RegExp should be /s, there's no need to put them in ' delimiters. i.e. to get your exec to run properly you should have:
var pattern = /KEY:(\S+) VAL:([^,]+)/g;
Second, you're assigning a boolean to kv which you don't want. The while will obviously only evaluate to true if it's not null so that's redundant. Instead you just need:
while (kv = pattern.exec(text)) {
That should get your code to work as you desire.
the syntax for pattern objects doesn't include quoting, such as:
var pattern=/KEY:(\S+) VAL:([^,]+)/g;
http://www.w3schools.com/jsref/jsref_regexp_exec.asp
It should be
var pattern = /KEY:(\S+) VAL:([^,]+)/g;
http://www.regular-expressions.info/ is a good place to start with.

Ambiguous interface of RegExp

Something very strange.
var body="Received: from ([195.000.000.0])\r\nReceived: from ([77.000.000.000]) by (6.0.000.000)"
var lastMath="";
var subExp = "[\\[\\(](\\d+\\.\\d+\\.\\d+\\.\\d+)[\\]\\)]"
var re = new RegExp("Received\\: from.*?"+subExp +".*", "mg");
var re1 = new RegExp(subExp , "mg");
while(ares= re.exec(body))
{
print(ares[0])
while( ares1 = re1.exec(ares[0]))
{
if(!IsLocalIP(ares1[1]))
{
print(ares1[1])
lastMath=ares1[1];
break ;
}
}
}
print(lastMath)
It outputs:
Received: from ([195.000.000.0])
195.000.000.0
Received: from ([77.000.000.000]) by (6.0.000.000)
6.0.000.000
6.0.000.000
But I think it should be:
Received: from ([195.000.000.0])
195.000.000.0
Received: from ([77.000.000.000]) by (6.0.000.000)
77.000.000.000
77.000.000.000
Because obviously "77.000.000.000" goes first. If I comment "break", output order is correct.
What's wrong with my code?
Note that regex grouping in Javascript (and most languages) does not work with a very obvious behavior with the * or + operators. For example:
js>r = /^(ab[0-9])+$/
/^(ab[0-9])+$/
js>"ab1ab2ab3ab4".match(r)
ab1ab2ab3ab4,ab4
In this case, you get the last group that matches and that's it. I'm not sure where this behavior is specified, but it can vary from language to language.
edit: What does IsLocalIP() do?
OK, I think the problem has to do with exec's statefulness (which may be why I don't use it; I use String.match()) -- if you're going to do this, you need to manually initialize the regex's lastindex property to 0, otherwise you get this behavior:
function weird(dobreak)
{
var s = "Received: from ([77.000.000.000]) by (6.0.000.000)"
var re1 = /[\[\(](\d+\.\d+\.\d+\.\d+)[\]\)]/mg
while (s2 = re1.exec(s))
{
writeln("s2="+s2);
if (dobreak)
break;
}
}
produces this result:
js>weird(true)
js>weird(true)
s2=[77.000.000.000],77.000.000.000
js>weird(true)
s2=(6.0.000.000),6.0.000.000
js>weird(true)
js>
You'll note that the same function gets three different results, which implies statefulness is mucking things up for some bizarre reason (Javascript is caching/interning the regex somehow? I'm using JSDB which uses Spidermonkey = Firefox's javascript engine).
So if I change the code to the following:
function notweird(dobreak)
{
var s = "Received: from ([77.000.000.000]) by (6.0.000.000)"
var re1 = /[\[\(](\d+\.\d+\.\d+\.\d+)[\]\)]/mg
re1.lastIndex = 0;
while (s2 = re1.exec(s))
{
writeln("s2="+s2);
if (dobreak)
break;
}
}
Then I get the expected behavior:
js>notweird(true)
s2=[77.000.000.000],77.000.000.000
js>notweird(true)
s2=[77.000.000.000],77.000.000.000
js>notweird(true)
s2=[77.000.000.000],77.000.000.000

Categories

Resources