What JavaScript library should I use for parsing URL parameters? - javascript

How do I parse URL parameters in JavaScript? (These are the parameters I would ordinarily call GET parameters or CGI parameters, but in this case the page is basically submitting to itself, not a server, so there is no GET request and definitely no CGI program.)
I've seen a number of routines on the net that I can copy, but I have no idea how robust any of them are. I'm used to other languages like Perl and Java where I can rely on an extremely well-tested and robust library that I know will handle millions of little edge-cases in the standard. I would like the same here, rather than just cutting and pasting an example.

jQuery URL Utils or jQuery URL Parser.

Here's are two simple functions that do the job : http://adamv.com/dev/javascript/querystring
Here is a sample of the API Reference :
var qs = new Querystring();
// Parse a given querystring
var qs2 = new Querystring("name1=value1&name2=value2");
var v1 = qs2.get("name1");
var v3 = qs2.get("name3", "default value");

If it's "submitting to itself," do you need to do GET parameters?
But if you do, most browsers now have the decodeURIComponent function which will handle individual parameters; your job is to split them on & (String#split will do that nicely). If you want a library, jQuery and Prototype are both well-used and tested.

The best way I have found is to simply do it yourself and funnel the params into a global key/value object.
Getting quer params is simple...
just take a couple of .split()'s
var myquery = thewholeurl.split("?")[1]; //will get the whole querystring with the ?
then you can do a
myparams = myquery.split("&")
then you can do
for each param in myparams
{
temp = param.split("=");
mykeys.push(temp[0]);
myvalues.push(temp[1]);
OR
myObject[temp[0]] = temp[1];
}
It's just a matter of style.
This is not perfect code, just psuedo stuff to give you the idea.

I use the parseUri library available here:
http://stevenlevithan.com/demo/parseuri/js/
It allows you to do exactly what you are asking for:
var uri = 'http://google.com/?q=stackoverflow';
var q = uri.queryKey['q'];
// q = 'stackoverflow'
I've been using it for a while so far and haven't had any problems.

I found this useful for simple url parsing, modifying url (like adding new query params): https://github.com/derek-watson/jsUri

I think this library would work quite well, it is independent so you can use it with JQuery or with YAHOO or Dojo, another advantage is that it is pretty well documented.
http://www.openjsan.org/doc/t/th/theory/HTTP/Query/0.03/lib/HTTP/Query.html
You can use HTTP.Query to do all of the work for you in this case. It is only like 1.2 KB compressed so you could even include it in a bigger library if you wanted.

I recommend query-string library
Installing:
npm install query-string
Usage:
import queryString from 'query-string';
console.log(location.search);
//=> '?foo=bar'
const parsed = queryString.parse(location.search);
console.log(parsed);
//=> {foo: 'bar'}
parsed.foo = 'unicorn';
parsed.ilike = 'pizza';
const stringified = queryString.stringify(parsed);
//=> 'foo=unicorn&ilike=pizza'
location.search = stringified;
// note that `location.search` automatically prepends a question mark
console.log(location.search);
//=> '?foo=unicorn&ilike=pizza'
https://www.npmjs.com/package/query-string

Javascript has no built in support for URL parameters.
Anyway, the location.search property returns the portion of current page URL starting from the question mark ('?').
From this, you can write your own parameter parser or you can make use of one of those available in most common Javascript frameworks, such as JQuery and similar.

Related

Is there any way of getting the GET parameters with pure Javascript?

Let's say I have a page called https://randompagename.com, I know I can send GET parameters to this page using this syntax: https://randompagename.com/?parameter1="one"&parameter2="two".
I also know that on a Node.js web app I have an easy way of getting these parameters inside a variable. However, when I'm using pure frontend Javascript without Node.js, I usually solve this problem with something like:
const myURL = decodeURI(window.location.href)
This way, I discover that my page is https://randompagename.com/?parameter1="one"&parameter2="two" and then I can parse it excluding everything after the first = sign and then splitting everything on &. Well, even though this is functional I'm probably missing an easier way of solving this problem. How can I get GET parameters on a page without using any library?
You can use the URL object https://developer.mozilla.org/en-US/docs/Web/API/URL
If the URL of your page is https://example.com/?name=Jonathan%20Smith&age=18 you could parse out the name and age parameters using:
let searchString = (new URL(document.location)).search; //?name=Jonathan%20Smith&age=18
let params = (new URL(document.location)).searchParams;
let name = params.get('name'); // is the string "Jonathan Smith".
let age = parseInt(params.get('age')); // is the number 18

Javascript ES6 TemplateString a TemplateString

I am using mustache to build out a single string, replacing several variables within it. I would love to use a TemplateString instead, but I need to resolve my string at runtime, and not at code-compile time since I am reading the template string from an external source.
To be clear:
// mustachy example
// template is "foo{{who}}" and myData.whmustao = "manchu"
let myResult = mustache.render(getMyTemplate(),myData);
console.log(myResult); // "foomanchu"
This is pretty lightweight, and I would love to use a TemplateString, but as the example below aludes to - I can't imagine a way to externally provide the string in the first place...
// ES6xy example
let myResult = `foo${myData.who}`; // can't get this at runtime
console.log(myResult); // "foomanchu"
But, I can't imagine a straight-forward, clean, non-sneaky way of achieving this. Can you?
I'm assuming that you're loading data on the client and want to generate a string based on the data returned. You could have a function available that returns the generated string for you
function generateString(val1, val2) {
return `foo${val1} bar${val2};
}
can you call that function on the client as a result of an api call that gets val1 and val2?
this strategy would also work on the server if you delay your response until you have all the data you need
put the template-string into a function, and pass myData
let renderMyTemplate = data => `foo${data.who}`;
//or
let renderMyTemplate = ({who}) => `foo${who}`;
let myResult = renderMyTemplate(myData);
console.log(myResult);
Thank you for your replies and creative solutions. However, I thought that there was no solution because TemplateStrings are an in-code feature, whereas other template solutions (like mustache) are a data-driven feature.
Put in other words, ES6's Template Strings is a language feature which limits its functionality to static in-code strings. Any other imagined flexibilities must rely on dynamic execution of a code you inject into your application, which is every hacker's dream.
So the answer to my original thought, as to whether Mustache is overkill for a simple string that is not hard-coded in your source - is NO. Mustache is the acceptable solution for that scenario.

Use Regex in Javascript to get the filename in a URL

I'm using JavaScript to try and get the filename from the URL.
I can get it using this:
var fn=window.location.href.match(/([^/])+/g);
alert(fn[fn.length-1]); // get the last element of the array
but is there an easier way to get it (e.g., without having to use fn[fn.length-1]
Thanks!!
Add a $ at the end so you only get the last part:
window.location.href.match(/[^/]+$/g);
Personally, I try to use simple string manipulation for easy tasks like this. It makes for more readable code (for a person not very familiar with RegEx).
var url = window.location.pathname;
var filename = url.substring(url.lastIndexOf('/')+1);
Or simply:
var filename = window.location.pathname.substring(window.location.pathname.lastIndexOf('/')+1);
Additional Information
Not that it matters for something so trivial, but this method is also more performant than RegEx: http://jsperf.com/get-file-name
How about:
window.location.href.match(/\/([^/]+)$/)[1];
you can use .pop() to get the last element of an array;
alert(fn.pop());
There is a jQuery plugin that makes it easy to parse URLs and provide access to their different parts. One of the things it does is return the filename. Here's the plugin on GitHub:
https://github.com/allmarkedup/jQuery-URL-Parser
I would recommend using that and avoid reinventing the wheel. Regular expressions is an area of programming where this is particularly applicable.
I recommend to also remove any '#' or '?' string, so my answer is:
var fn = window.location.href.split('/').pop().replace(/[\#\?].*$/,'');
alert(fn);
split('/').pop() removes the path
replace(/[\#\?].*$/,'') replace '#' or '?' until the end $ by empty string

Passing 2 URL Parameters?

I need to pass 2 URL parameters in a URL. The URL originates in an email and the user will click the link directing them to my site. The first parameter triggers a script on the page the second parameter is for a module my CMS will render from the parameter.
First Parameter is : message=1 (This parameter triggers the javascript)
The second Parameter is: name={tag_recipientfirstname} (My CMS will render the module)
The script that is called for the first looks like this:
<script type="text/javascript">
var $j = jQuery.noConflict();
$j(document).ready(function() {
var url = window.location.href;
url = url.toLowerCase();
if (url.indexOf('message=1') != -1) {
$j("a.message").colorbox({
open:true
});
}
$j("a.message").colorbox(); //not related to URL parameter
});
</script>
The second parameter is used on the page as:
<div>
<p>{ module_url,name} (again CMS will render this module)</p>
</div>
EDIT
I realize I left a couple things out:
First: How do I pass both parameters so they will both function as listed above?
And the CMS I am using is Business Catalyst.
//split the `location.search` string at the ampersands
var search_arr = window.location.search.replace('?', '').split('&'),
len = search_arr.length,
get_vars = {},
tmp = [];
//iterate through the key/value pairs and add them to the `get_vars` object
for (var i = 0; i < len; i++) {
tmp = search_arr[i].split('=');
get_vars[tmp[0]] = tmp[1];
}
//you can now access your GET variables through the `get_vars` object like: `get_vars.name`
//you can check for the existence of a certain GET variable like this
if (typeof(get_vars['message-1']) != 'undefined') {
$j("a.message").colorbox({
open:true
});
}
Here is a demo:http://jsfiddle.net/aBH8K/1/ (http://jsfiddle.net/aBH8K/1/show/?message-1=3 to see with get var)
Some related documentation:
window.location: https://developer.mozilla.org/en/DOM/window.location
Your question is not so much about generic development, rather a very specific commercial product; I do not know which plan you subscribed (free o pay-for?) with them but in any case it would be best to go through their support (see also my conclusion)
Nevertheless I'll try to put you on the right track.
Your questions
First,
the url in the email
In the email you will have somehow to build a link with the two parameters you want as #Jasper is explaining.
this means something like:
http://yourwebsite.com/destination/path/?message=1&name={tag_recipientfirstname}
Everything after the question mark is a GET query string.
Parameters are separated by the "&" symbol.
I definitely don't know how properly build urls in BC emails, but I feel like it should be an automated somewhere allowing you to specify additional parameters if you need.
the javascript
What you got will still work. It's not very nice, and you can use Jasper's solution or any other such as How can I get query string values in JavaScript?
Nothing to do then unless you want to make it better and more robust.
Business Catalyst (the page)
You usually have ways in a CMS to retrieve get parameters. Often something like
{ GET.param_name }
One step back
I am no expert with BC, but I have the feeling that you are taking a complicate path for something that is probably already baked in.
Again I suggest you go into their support section (though it's rather confusing I must say!) and try to understand what's the best way to achieve your objective. There are always many ways to skin a poor cat.
If you are getting support in your plan, definitely go that way and try to explain what you objectives are rather then how to achieve the technical solution that you think is the good one!

Using Xpath selectors to extract / combine data from Javascript Objects?

I'm quite fond of CakePHP Set class, it comes with a few awesome tools i now love. I use it mainly to extract or combine arrays.
I was wondering if there was a way to do just that with javascripts Objects/Arrays of data.
// Desired Usage:
var users = {User: {0:{id:1,name:'A'},1:{id:2,name:'B'}}}
var results = $.extract('/User/id', users);
// results returns:
// {0:1,1:2};
// /User[id>2][<5] Selects all Users with an id > 2 but < 5
It could support on jQuery or maybe just Sizzle.
Do i have to develop thoses functions from zero or is there already some native/plugin xpath selector/extractor support out there ? Can Sizzle do this ?
Thanks a lot!
Look for that library http://code.google.com/p/jsonpath/
Not sure, whether it could process request exactly in this syntax: User[id>2][<5],
but it's rather powerful library and should have similar feature.
Even if there's no function for request parts like "[<5]", you may call
.slice(0, 5);

Categories