Get part of a url in javascript before the parameters - javascript

I've a url ('https://xyz.abc.org.com/v1.5/wth/data/analysis/geo?run=run1&aaa=some') which remains the same till 'v1.5' till any api calls.
So I need to get the last part 'geo' out of the url.
Here's my code:
var testUrl = 'https://xyz.abc.org.com/v1.5/wth/data/analysis/geo?run=run1&aaa=some';
console.log(testUrl.substring(testUrl.lastIndexOf('/')));
But, this returns - 'geo?run=run1&aaa=some', while I want 'geo'.
How do I fix this?
Also, I can't use some numbers to get the substring out of it, as that part of the url will be different for different api calls.
I just need the part of the url after last '/' and before '?' or '&'.

Last index of / and first index of ?. In between these is the text you require
var testUrl = 'https://xyz.abc.org.com/v1.5/wth/data/analysis/geo?run=run1&aaa=some';
console.log(testUrl.substring(testUrl.lastIndexOf('/')+1, (testUrl.indexOf('?') > testUrl.lastIndexOf('/') + 1)) ? testUrl.indexOf('?') : testUrl.length );
// prints geo

This will work whether there is a parameter list or not:
testUrl.substring(testUrl.lastIndexOf('/')+1, testUrl.indexOf('?') > 0 ? testUrl.indexOf('?') : testUrl.length)

Why not just get rid of everything starting from the question mark? You can modify the string you already have.
var testUrl = "https://xyz.abc.org.com/v1.5/wth/data/analysis/geo?run=run1&aaa=some";
var extractWithParams = testUrl.substring(testUrl.lastIndexOf('/'));
var extractWithoutParams = extractWithParams.split("?")[0];
console.log(extractWithoutParams);
// you could just do in all in one go,
// but i wrote it that way to make it clear what's going on
// testUrl.substring(testUrl.lastIndexOf('/')).split("?")[0];
Alternatively, you could also try
var extractWithParams = testUrl.substring(testUrl.lastIndexOf('/'));
var n = extractWithParams.indexOf("?"); // be careful. there might not be a "?"
var extractWithoutParams = extractWithParams.substring(0, n != -1 ? n : s.length);
I'm not sure which one performs better, but I'd imagine that the first one might be slower since it involves array operations. I might be wrong on that. Either way, if it's a one-time operation, the difference is negligible, and I'd go with the first once since it's cleaner.

Related

How to access the first two digits of a number

I want to access the first two digits of a number, and i have tried using substring, substr and slice but none of them work. It's throwing an error saying substring is not defined.
render() {
let trial123 = this.props.buildInfo["abc.version"];
var str = trial123.toString();
var strFirstThree = str.substring(0,3);
console.log(strFirstThree);
}
I have tried the above code
output of(above code)
trial123=19.0.0.1
I need only 19.0
How can i achieve this?
I would split it by dot and then take the first two elements:
const trial = "19.0.0.1"
console.log(trial.split(".").slice(0, 2).join("."))
// 19.0
You could just split and then join:
const [ first, second ] = trial123.split('.');
const result = [ first, second ].join('.');
I have added a code snippet of the work: (explanation comes after it, line by line).
function getFakePropValue(){
return Math.round(Math.random()) == 0 ? "19.0.0.1" : null;
}
let trial123 = getFakePropValue() || "";
//var str = trial123.toString();
// is the toString() really necessary? aren't you passing it along as a String already?
var strFirstThree = trial123.split('.');
//var strFirstThree = str.substring(0,3);
//I wouldn't use substring , what if the address 191.0.0.1 ?
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
Because you are using React, the props value was faked with the function getFakePropValue. The code inside is irrelevant, what I am doing is returning a String randomly, in case you have allowed in your React Component for the prop to be empty. This is to show how you an create minimal robust code to avoid having exceptions.
Moving on, the following is a safety net to make sure the variable trial123 always has a string value, even if it's "".
let trial123 = getFakePropValue() || "";
That means that if the function returns something like null , the boolean expression will execute the second apart, and return an empty string "" and that will be the value for trial123.
Moving on, the line where you convert to toString I have removed, I assume you are already getting the value in string format. Next.
var strFirstThree = trial123.split('.');
That creates an array where each position holds a part of the IP addrss. So 19.0.0.1 would become [19,0,0,1] that's thanks to the split by the delimiter . . Next.
if(strFirstThree.length >= 2)
console.log(strFirstThree.splice(0,2).join("."));
else
console.error("prop was empty");
This last piece of code uses the conditional if to make sure that my array has values before I try to splice it and join. The conditional is not to avoid an exception, since splice and join on empty arrays just returns an empty string. It's rather for you to be able to raise an error or something if needed. So if the array has values, I keep the first two positions with splice(0,2) and then join that array with a '.'. I recommend it more than the substr method you were going for because what if you get a number that's 191.0.0.1 then the substr would return the wrong string back, but with splice and join that would never happen.
Things to improve
I would strongly suggest using more human comprehensible variables (reflect their use in the code)
The right path for prop value checking is through Prop.Types, super easy to use, very helpful.
Happy coding!

Use window to execute a formula instead of using eval

My code need to execute a forumla (like Math.pow(1.05, mainObj.smallObj.count)).
My path is :
var path = mainObj.smallObj.count;
as you can see.
If needed, my code can split all variable names from this path and put it in an array to have something like :
var path = ["mainObj", "smallObj", "count"];
Since I don't want to use eval (this will cause memory leaks as it will be called many times every seconds), how can I access it from window?
Tried things like window["path"] or window.path.
If it is always unclear, let me know.
Thanks in advance for any help.
EDIT: forget to tell that some config are written in JSON, so when we take the formula, it's interpreted as "Math.pow(1.05, mainObj.smallObj.count)" so as a string.
I would say there are better solutions then eval, but it depends how the forumla can be structured. It could be precompiled using new Function (this is also some kind of eval) but allowing it to be called multiple times without the need to recompile for each invocation. If it is done right it should perform better then an eval.
You could do something like that:
var formula = {
code : 'Math.pow(1.05, mainObj.smallObj.count)',
params : ['mainObj']
}
var params = formula.params.slice(0);
params.push('return '+formula.code);
var compiledFormula = Function.apply(window, params);
//now the formula can be called multiple times
var result = compiledFormula({
smallObj: {
count: 2
}
});
You can get the path part reconciled by recursively using the bracket notation:
window.mainObj = { smallObj: { count: 2 } };
var path = ["mainObj", "smallObj", "count"];
var parse = function (obj, parts) {
var part = parts.splice(0, 1);
if (part.length === 0) return obj;
obj = obj[part[0]];
return parse(obj, parts);
};
var value = parse(window, path);
alert(value);
Basically, parse just pulls the first element off the array, uses the bracket notation to get that object, then runs it again with the newly shortened array. Once it's done, it just returns whatever the result of the last run is.
That answers the bulk of your question regarding paths. If you're trying to interpret the rest of the string, #t.niese's answer is as good as any other. The real problem is that you're trusting code from an external source to run in the context of your app, which can be a security risk.

If Statement Have A String And Other String (Make To List)

Sorry i cant find the tutorial in google because i dont know the keyword...
var currentURL=location.href;
var str = currentURL;
if(str == "http://web.com/blabla" || str == "http://web.com/bleble"){
window.location = "http://web.com/ban";
} else {
}
How to make str == "http://web.com/blabla" || str == "http://web.com/bleble" to list ? so if i want to input some url again, i just input the url to the list. Can give me the code or link tutorial ???
Basically you'll need to place all of your URL's into an array and then iterate over the array checking each item.
var urls = ['http://web.com/','http://web.net/','http://web.org'];
var current_url = '...';
for (var i = 0; i < urls.length; i++){
if (current_url == urls[i]){
window.location = "http://web.com/ban";
break; // exit the loop since we have already found a match
}
}
The break command will terminate the loop and stop searching the array for matching URLs. Since the action you want to take needs to happen if any of the URLs match, it's enough for one to match in order to stop searching.
Lists are called arrays in javascript, and are declared using square brackets, like this: var badUrls = ["http://web.com/blabla", "http://web.com/bleble"].
To check whether the current URL appears in the array, you can use the .indexOf function of the array, which will return the first position in the array where the string you provide can be found (starting with 0 for the first element), or -1 if it doesn't exist. For example, if you have an array var arr = ["foobar", "foo", "bar", "baz"], and you do arr.indexOf("foo"), you get 1 because it's the 2nd element in the array. If instead you do arr.indexOf("fooba"), you will get -1 because none of the elements in the array are fooba exactly. In your code, you want to redirect the user if badUrls.indexOf(str) > -1. You can get more information on indexOf in the MDN Documentation.
That makes your code look like:
var currentURL=location.href;
var str = currentURL;
var badUrls = ["http://web.com/blabla", "http://web.com/bleble"]
if(badUrls.indexOf(str) > -1){
window.location = "http://web.com/ban";
} else {
}
window.location is a browser object, it you want the page to go to http://web.com/ban, you should use
window.location.href = "http://example.com/ban";
However, it looks like you are trying to prevent people from visiting pages using JavaScript. This is extremely insecure, because anyone that lists your code will see which URLs you're trying to protect and immediately request them. If they request those URLs with JavaScript disabled, or using curl, the pages will be delivered.
You should protect the pages with server side configuration. With Apache, you can use the Allow/Deny configuration or RewriteRules.

Weird JavaScript Code

for (var i=a.length-1;i>0;i--) {
if (i!=a.indexOf(a.charAt(i))) {
a=a.substring(0,i)+a.substring(i+1);
}
}
I found this in a web app I'm auditing, it just baffles me why it's there.
I can't seem to see a case where i!=a.indexOf(a.charAt(i)) would be false.
The value the pass to it is:
a = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
There is no comment either //sigh
This would be true for repeated characters, since indexOf finds the first index of a string, and you're searching from the end. Example:
var a = "xyzxyz";
On first iteration, i === 4, a.charAt(4) === "x", and a.indexOf("x") === 0. So 4 !== 0.
It then sets a = a.substring(0, 4) + a.substring(5). Recalling at substring is inclusive in the first index but exclusive in the last index, that means in this case a = "xyz" + "yz", so we have removed the duplicate "x" from the string.
Since the loop traverses backward, this will continue to work even for characters repeated more than once; you can see that the portion a.substring(i + 1) will always have been covered by the algorithm already, i.e. not contain any duplicates.
As always when encountering this type of thing, applying the extract method refactoring would be a great way to make the code clearer. (Even better than commenting it!) So if you just pulled this out into a method, the code could become a = removeDuplicateChars(a), and everyone is much happier.

Syntax explanation please

I'm trying to understand 2 different lines of code below. My javascript is weak, trying to improve it with jquery (hmmmm)
What I'm trying to use the drag sort plugin from http://dragsort.codeplex.com/ specifically I'm using the http://dragsort.codeplex.com/SourceControl/changeset/view/74794#1025059 example.
I've gotten to the stage now where I've used this approach
var serialStr = "";
$("#list1 li").each(function(i, elm) {
serialStr = (i > 0 ? "|" : "") + $(elm).children().html();
});
The example has the following.
var serialStr = new Array();
$("#list1 li").each(function(i, elm) {
serialStr[] = = $(elm).attr("itemId");
});
The reason I have the first approach is that I was testing everything out and its what they had in the HTML example. I'm now trying to save the state so I've moved onto the php example.
So my question is what is the primary difference going on in the different lines here? My understanding of the first line is that its selecting each child element inside of the li tag on list1 I don't really get the (i > 0 ? "|" : "") bit.
In the second snipplet from what I understand its selecting every attribute with the itemID assignee in list1 li ?
serialStr[] = (i > 0 ? "|" : "") +$(elm).children().html() is a shorthand if-clausule. It does the same as:
if(i > 0) {
serialStr[] = "|" +$(elm).children().html();
} else {
serialStr[] = "" +$(elm).children().html();
}
The expression (i > 0 ? "|" : "") is using the conditional operator condition ? expr1 : expr2 to not to prefix the first value with | but only every following values.
But the expression serialStr[] = = $(elm).attr("itemId") is invalid syntax. Javascript does not have a push operator [] like PHP has. Use Array.prototype.push instead.
I don't think you've pasted the code exactly as neither snippet makes sense. The first seems to want to be concatenating strings together, but is missing the += that would make that happen; the second is making a list, presumably to join() together afterwards, but is using some odd []= syntax that does not exist in JavaScript.
I don't really get the (i > 0 ? "|" : "") bit.
First time round the loop, pick "", subsequent times pick "|". This is the traditional way to make a string where each element is separated by a character.
But join() is generally a cleaner way to do that, and you can use map() to run a function over an array returning a new array, instead of having to manually create one:
var itemIds= $('#list1 li').map(function() {
return $(this).attr('itemId');
}).get().join('|');
(Or $(this).html() if you really want to get the HTML content, which sounds a bit questionable.)
map() is a jQuery function but ECMAScript Fifth Edition has a map() method on plain arrays too. About map in general.

Categories

Resources