Last active
April 20, 2021 10:55
-
-
Save zfedoran/ad6194b1dae66ff038e3ae9ab77c2241 to your computer and use it in GitHub Desktop.
Basic URL handler with query param support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example urls.js file for a Vue or React project | |
// ------------------------------------------------------------------------------------- | |
// URLs.js | |
// ------------------------------------------------------------------------------------- | |
/* | |
* Get the url query parameters from the current URL in the address bar | |
*/ | |
function get_url_params() { | |
var url_params = {}; | |
var match, | |
pl = /\+/g, // Regex for replacing addition symbol with a space | |
search = /([^&=]+)=?([^&]*)/g, | |
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, | |
query = window.location.search.substring(1); | |
while (match = search.exec(query)) { | |
url_params[decode(match[1])] = decode(match[2]); | |
} | |
return url_params; | |
} | |
/* | |
* This function combines "old_params" and "new_params" objects and serializes | |
* them into a query string. Repeated/duplicate params are not supported. | |
* | |
* Example: | |
* | |
* Given the existing query params, give me a new query string sorting by date | |
* but remove the page and keep everything else. | |
* | |
* serialize_params({ page: 5, search_term: 'hello' }, { sort: 'by_date' }, ['page'], true); | |
* > "?search_term=hello&sort=by_date" | |
*/ | |
function serialize_params(old_params={}, new_params={}, remove_params=[], keep_params=false) { | |
if (keep_params) { | |
const param_obj = { ...old_params, ...new_params }; | |
const param_str = '?' + Object.keys(param_obj) | |
.filter((key)=>!remove_params.includes(key)) // exclude any params that are in "remove_params" | |
.map((key) => `${key}=${param_obj[key]}`).join('&'); | |
return param_str.length > 1 ? param_str : ''; | |
} | |
return ''; | |
} | |
/* | |
* This function wraps serialize_params(); allows for a single option parameter instead. | |
* | |
* Example: | |
* | |
* handle_params({ | |
* old_params: { page: 5, search_term: 'hello' }, | |
* new_params: { sort: 'by_date' }, | |
* remove_params: ['page'], | |
* keep_params: true | |
*); | |
* | |
* > "?search_term=hello&sort=by_date" | |
* | |
*/ | |
function handle_params({ old_params, new_params, remove_params, keep_params }) { | |
return serialize_params(old_params, new_params, remove_params, keep_params) | |
} | |
//module.exports = url_module; | |
const url_module = { | |
// Export the get_url_params function | |
get_url_params, | |
// Export a helper function to set the current url | |
goto(url) { window.location = url }, | |
// Initialize base properties | |
init(options = { web_base: '', api_base: '', /* anything else you need */ }) { | |
const web_base = options.web_base; | |
const api_base = options.api_base; | |
const old_params = get_url_params(); | |
const urls = { | |
// List your URL configuration here or pass it in through a variable. Keeping it simple here... Some examples below. | |
// PROJECTS | |
'core:project_list': ({}) => `${web_base}/project/`, | |
'core:project_details': ({project}) => `${web_base}/project/${project}`, | |
// CAMPAIGNS | |
'core:campaign_list': ({}) => `${web_base}/project/campaign/`, | |
'core:campaign_details': ({campaign}) => `${web_base}/project/campaign/${campaign}`, | |
// API | |
'api:datasource_list': ({}) => `${api_base}/api/data/datasource`, | |
'api:datasource_detail': ({datasource}) => `${api_base}/api/data/datasource/${datasource}`, | |
'api:datasource_create': ({datasource}) => `${api_base}/api/data/datasource/new/${datasource}`, | |
} | |
return function reverse(name, args) { | |
if (typeof name == 'object' && name.length == 2) { | |
args = name[1]; | |
name = name[0]; | |
} | |
try { | |
return urls[name](args) + handle_params({...args, old_params}); | |
} catch (err) { | |
throw `Missing a URL on the front-end: "${name}"\n\n\t${err}` | |
} | |
} | |
} | |
} | |
// ------------------------------------------------------------------------------------- | |
// Example Usage | |
// ------------------------------------------------------------------------------------- | |
// Lets assume the current URL includes "http://...?page=5&search_term=foobar" | |
url_module.get_url_params() | |
// {page: "5", search_term: "foobar"} | |
// Lets initialize the module with our base URL(s) | |
const reverse = url_module.init({ web_base: 'localhost:8000/web/dashboard', api_base: 'localhost:3000' }) | |
// Basic Examples: | |
// ------------------------------------------------------------------------------------- | |
reverse('api:datasource_list', {}) | |
// "localhost:3000/api/data/datasource" | |
reverse('core:project_list', {}) | |
// "localhost:8000/web/dashboard/project/" | |
reverse('core:project_details', { project:'b6f54cec-9d58-11eb-bcb3-0242ac110002' }) | |
// "localhost:8000/web/dashboard/project/b6f54cec-9d58-11eb-bcb3-0242ac110002" | |
reverse('core:project_list', { keep_params: true }) | |
// "localhost:8000/web/dashboard/project/?page=5&search_term=foobar" | |
reverse('core:project_list', { keep_params: true, new_params: { sort: 'by_date' }}) | |
// "localhost:8000/web/dashboard/project/?page=5&search_term=foobar&sort=by_date" | |
reverse('core:project_list', { keep_params: true, new_params: { sort: 'by_date' }, remove_params: ['page']}) | |
// "localhost:8000/web/dashboard/project/?search_term=foobar&sort=by_date" | |
// Advanced Examples | |
// ------------------------------------------------------------------------------------- | |
const SEARCH_ACTION = ({ term }) => [ | |
'core:campaign_list', { | |
keep_params: true, | |
remove_params: [ 'page' ], | |
new_params: { search_term: term } | |
} | |
] | |
reverse(SEARCH_ACTION({ term: 'hello world' })) | |
// "localhost:8000/web/dashboard/project/campaign/?search_term=hello world" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment