Extracting a certain value from the URL - javascript

What do you think will be the most optimal way to extract the value from the window.location.href.
This is the example http://localhost:3000/brand/1/brandCategory/3
the Route will always be the same, just the numbers will change depending on what is chosen.
the brand id will be the first number and the category id is the second I need help extracting them in a react/typescript project.
keep in mind that it should work when the page is deployed and that the start of the URL will have a different name than localhost, but the routes will be the same.
I tried doing it with string formatting, but it's really unpredictable, tried also with regex but when I try to extract it typescript cries about the object is possibly 'null', what can you suggest?
Number(window.location.href.match(new RegExp(/\/[0-9]\//,'gm'))[0].split('/')[1])
this is the regex try.

You can split the path, remove empty segments and retrieve the numbers by position:
const url = 'http://localhost:3000/brand/1/brandCategory/3';
const segments = url.split('/').filter(seg => seg);
const length = segments.length;
console.log(`brand: ${segments[length - 3]}, brandCategory: ${segments[length - 1]}`);
I added the filter for the case of a trailing slash.
You could replace the filter with endsWith
const url = 'http://localhost:3000/brand/1/brandCategory/3';
const segments = url.split('/');
const length = url.endsWith('/') ? segments.length - 1 : segments.length;
console.log(`brand: ${segments[length - 3]}, brandCategory: ${segments[length - 1]}`);

Related

Clean way to get value from string in Javascript

I have this string https://pokeapi.co/api/v2/pokemon/6/
I would like to extract the value after pokemon/ in this case 6. This represent Pokémon ids which could span between 1 -> N
I know this is pretty trivial and was wondering a nice solution for future proofing. Here is my solution.
const foo= "https://pokeapi.co/api/v2/pokemon/6/"
const result = foo.split('/') //[ 'https:', '', 'pokeapi.co', 'api', 'v2', 'pokemon', '6', '' ]
const ids = result[6]
You can grab the value after the last / character like so:
const pokemonID = foo.substring(foo.lastIndexOf("/") + 1)
Using String.lastIndexOf to get the final index of the slash character, and then using String.substring with only a single argument to parse the part of the string after that last / character. We add 1 to the lastIndexOf to omit the final slash.
For this to work you need to drop your final trailing slash (which won't do anything anyways) from your request URL.
This could be abstracted into a utility function to get the last value of any url, which is the biggest improvement over using a split and find by index approach.
However, beware, it will take whatever the value is after the last slash.
Using the string https://pokeapi.co/api/v2/pokemon/6/pokedex would return pokedex.
If you are using Angular, React, Vue etc with built in router, there will be specific APIs for the framework that can get the exact parameter you need regardless of URL shape.
You should use the built-in URL API to do the splitting correctly for you:
const url = new URL("https://pokeapi.co/api/v2/pokemon/6/");
Then you can get the pathname and split that:
const path = url.pathname.split("/");
After you split it you can get the value 6 by accessing the 5th element here:
const url = new URL("https://pokeapi.co/api/v2/pokemon/6/");
const path = url.pathname.split("/");
console.log(path[4]);
you could also do something like:
url.split('pokemon/')[1].split('/')[0]
Here is what I would do
const result = new URL(url).pathname.split('/');
const id = result[4];
I am not sure if this is better than yours
const foo= "https://pokeapi.co/api/v2/pokemon/6/"
const result = foo.indexOf("pokemon/");
const id_index = result + 8
const id = foo[id_index];

Check if string matches

I've got a dataset, and each object has a promoUrl and a promoNumber, structured like so:
const phoneNumbers = [
{
promoUrl: '/interior-doors/',
promoNumber: '589-918-0710',
},
{
promoUrl: '/promo4/',
promoNumber: '307-789-8615',
},
];
On first load a cookie is set, containing the referral url (the const referrer in the code below) and the referral URL is passed to a reduce function allowing me to look for a URL, find the associated phone number, and then display that number dynamically.
const url = referrer;
const promoNumber = promoResults.reduce((promoNumber: string, results: any) => {
const hasPromo = url === results.promoUrl;
if (hasPromo) {
return results.promoNumber;
}
return promoNumber;
}, '');
However right now when it finds the URL it will only match the number if the cookie value matches the promoUrl exactly. Once this is live I won't be in charge of setting the promoUrls, and that task will go to non-developers. How do I set this so it works as long as the string contains matching characters, i.e. instead of needing /interior-doors/ it would work if the promoUrl is interior-doors or /interior-doors? Really anything so long as the string includes matching characters?
I've tried editing my hasPromo const using .includes():
const hasPromo = url.includes(results.promoUrl);
But it still hasn't worked for me.
have you log your url and results.promoUrl
suggestion is logs type and value of both keys ( url and promoUrl)
Figured this out after a bit of digging and some help in the comments from Robert Harvey.
All I need to do was modify the hasPromo const to check results.promoUrl first.
const hasPromo = results.promoUrl.includes(url);
This worked exactly like I need it to.

Javascript regex parse complex url string

I need to parse a complex URL string to fetch specific values.
From the following URL string:
/api/rss/feeds?url=http://any-feed-url-a.com?filter=hot&format=rss&url=http://any-feed-url-b.com?filter=rising&format=rss
I need to extract this result in array format:
['http://any-feed-url-a.com?filter=hot&format=rss', 'http://any-feed-url-b.com?filter=rising&format=rss']
I tried already with this one /url=([^&]+)/ but I can't capture all correctly all the query parameters. And I would like to omit the url=.
RegExr link
Thanks in advance.
This regex works for me: url=([a-z:/.?=-]+&[a-z=]+)
also, you can test this: /http(s)?://([a-z-.?=&])+&/g
const string = '/api/rss/feeds?url=http://any-feed-url.com?filter=hot&format=rss&url=http://any-feed-url.com?filter=latest&format=rss'
const string2 = '/api/rss/feeds?url=http://any-feed-url.com?filter=hot&format=rss&next=parm&url=http://any-feed-url.com?filter=latest&format=rss'
const regex = /url=([a-z:/.?=-]+&[a-z=]+)/g;
const regex2 = /http(s)?:\/\/([a-z-.?=&])+&/g;
console.log(string.match(regex))
console.log(string2.match(regex2))
have you tried to use split method ? instead of using regex.
const urlsArr = "/api/rss/feeds?url=http://any-feed-url-a.com?filter=hot&format=rss&url=http://any-feed-url-b.com?filter=rising&format=rss".split("url=");
urlsArr.shift(); // removing first item from array -> "/api/rss/feeds?"
console.log(urlsArr)
)
which is going to return ["/api/rss/feeds?", "http://any-feed-url-a.com?filter=hot&format=rss&", "http://any-feed-url-b.com?filter=rising&format=rss"] then i am dropping first item in array
if possible its better to use something else then regex CoddingHorror: regular-expressions-now-you-have-two-problems
You can matchAll the url's, then map the capture group 1 to an array.
str = '/api/rss/feeds?url=http://any-feed-url-a.com?filter=hot&format=rss&url=http://any-feed-url-b.com?filter=rising&format=rss'
arr = [...str.matchAll(/url=(.*?)(?=&url=|$)/g)].map(x => x[1])
console.log(arr)
But matchAll isn't supported by older browsers.
But looping an exec to fill an array works also.
str = '/api/rss/feeds?url=http://any-feed-url-a.com?filter=hot&format=rss&url=http://any-feed-url-b.com?filter=rising&format=rss'
re = /url=(.*?)(?=&url=|$)/g;
arr = [];
while (m = re.exec(str)) {
arr.push(m[1]);
}
console.log(arr)
If your input is better-formed in reality than shown in the question and you’re targeting a modern JavaScript environment, there’s URL/URLSearchParams:
const input = '/api/rss/feeds?url=http://any-feed-url-a.com?filter=hot%26format=rss&url=http://any-feed-url-b.com?filter=rising%26format=rss';
const url = new URL(input, 'http://example.com/');
console.log(url.searchParams.getAll('url'));
Notice how & has to be escaped as %26 for it to make sense.
Without this input in a standard form, it’s not clear which rules of URLs are still on the table.

regex to match first occruence and everything in between until last match

I may be thinking this about the wrong way.
The first three (...)'s are generated and could be any number. I only want to catch these first set of items and allow the user to use () inside of their custom string.
Test String
(374003) (C6-96738) (WR183186) R1|SALOON|DEFECTIVE|WiFiInfotainment|Hardware detects WIFI but unable to log in on the (JAMIE HUTBER) internet.:
Regex
/\(([^)]+)\)/g
Current output
 ["(374003)", "(C6-96738)", "(WR183186)", "(JAMIE HUTBER)"]
Desired Output
 ["(374003)", "(C6-96738)", "(WR183186)"]
You can use two ways to do that:
get only 3 items from array
add space to your regexp \(([^ )]+)\) (https://regex101.com/r/ZPdq35/1/)
Using the sticky option /y you can then use regEx's ability to find all occurrences..
This will then work, if there is not a space in JAMIE HUNTER, etc..
eg.
const re = /\s*\(([^)]+)\)/y;
const str = "(374003) (C6-96738) (WR183186) R1|SALOON|DEFECTIVE|WiFiInfotainment|Hardware detects WIFI but unable to log in on the (JAMIE HUTBER) internet.:";
let m = re.exec(str);
while (m) {
console.log(m[1]);
m = re.exec(str);
}

how to use javascript to extract numeric part of a url

I want to use javascript to extract a numeric part of a url. There is only ever supposed to be one set of numerals (aka - it will never be www.example.com/455/all/6). The set of numerals will not always be the same. How can I do this? I know that i can use this code
var urlPath = window.location.pathname;
to extract the url, but I don't know how to go further.
urlPath.match(/\d+/)[0] will get the numbers. It doesn't perform any sanity checks, though, and will fail if there are no numbers at all. For better results, try:
var t = urlPath.match(/\d+/);
t = t ? t[0] : null; // or some other default value, such as `0`

Categories