URL Parameter Parser

by Scott Kaye

JavaScript

console.clear();

// Normally this would be window.location.search
var search = "?Options.InnerProp=True&Options.ValuelessProp=&Options.MultiValue.Prop=One&Options.MultiValue.Prop=Two&Options.MultiValue.Prop=Three&Options.AnotherInnerProp=false&BaseProp=5";

function getParams() {
	var query = search.slice(1);
	var params = {};
	
	query.split("&").forEach(q => {
		var s = q.split("=");
		var key = decodeURIComponent(s[0]);
		var value = decodeURIComponent(s[1].replace(/\+/g, " "));
		var obj = params;
		
		if (key.indexOf(".") !== -1) {
			var keyPath = key.split(".");
			
			keyPath.slice(0, -1).forEach(part => {
				obj = obj[part] = obj[part] || {};
			});
			
			key = keyPath.slice(-1);
		}
		
		if (obj[key] != undefined) {
			if (!Array.isArray(obj[key])) {
				obj[key] = [obj[key], value];
			}
			else {
				obj[key].push(value);
			}
		}
		else {
			obj[key] = value;
		}
	});
	
	return params;
};

function buildASPNetParams(obj, base) {
	if (base) base += ".";
	else base = "";
	
	if (typeof obj === "string") return base.slice(0, -1) + "=" + obj;

	return Object.keys(obj).map(key => {
		if (Array.isArray(obj[key])) {
			return obj[key].map(value => {
				return buildASPNetParams(value, base + key);
			}).join("&");
		} else if (typeof obj[key] === "object") {
			return buildASPNetParams(obj[key], base + key);
		}
		
		return base + encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
	}).join("&");
}

console.log(getParams(), buildASPNetParams(getParams()), "?" + buildASPNetParams(getParams()) === search);