Last active
July 18, 2023 09:27
-
-
Save fproperzi/8fc5e74f195be921dc42c11e52288047 to your computer and use it in GitHub Desktop.
javascript tools
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
const getParameters = URL => JSON.parse(`{"${decodeURI(URL.split("?")[1]).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"')}"}`); | |
// getParameters("https://www.google.com.hk/search?q=js+md&newwindow=1"); | |
// {q: 'js+md', newwindow: '1'} | |
const uniqueArr = (arr) => [...new Set(arr)]; // unique array | |
const hashCode = (str) => [...str].reduce((s, c) => Math.imul(31, s) + c.charCodeAt(0) | 0, 0) >>> 0; // only positive numbers | |
const hashBCode = (str) => btoa([...str].reduce((s, c) => Math.imul(31, s) + c.charCodeAt(0) | 0, 0)); | |
const base62 = { | |
charset: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' | |
.split(''), | |
encode: integer => { | |
if (integer === 0) { | |
return 0; | |
} | |
let s = []; | |
while (integer > 0) { | |
s = [base62.charset[integer % 62], ...s]; | |
integer = Math.floor(integer / 62); | |
} | |
return s.join(''); | |
}, | |
decode: chars => chars.split('').reverse().reduce((prev, curr, i) => | |
prev + (base62.charset.indexOf(curr) * (62 ** i)), 0) | |
}; | |
/* minimized sprintf.js (C) 2021-present Denys Savchenko -- https://github.com/sdensys */ | |
const sprintf=function(a,e){var t,r,c=String(a),n=0,i=c.length,o="";for(t=0;t<i;t++){if("%"!=c.charAt(t)){o+=c.charAt(t);continue}if(t+1>=i)break;if("%"==c.charAt(++t)){o+="%";continue}var h,s=!1,b=" ",$=!1,l=0,f=!1;if("+"==c.charAt(t)&&(f=!0,++t>=i))break;if(" "==c.charAt(t)||"0"==c.charAt(t)){if(b=c.charAt(t),++t>=i)break}else if("'"==c.charAt(t)){if((t+=2)>=i)break;b=c.charAt(t-1)}if("-"==c.charAt(t)&&($=!0,++t>=i))break;for(;c.charAt(t)>="0"&&"9">=c.charAt(t)&&(l=10*l+Number(c.charAt(t)),!(++t>=i)););if(t>=i)break;if("."==c.charAt(t)){if(s=0,++t>=i)break;for(;c.charAt(t)>="0"&&"9">=c.charAt(t)&&(s=10*s+Number(c.charAt(t)),!(++t>=i)););if(t>=i)break}if(void 0!=(h=e[n++])){switch(r="",c.charAt(t)){case"u":r+=Math.abs(parseInt(h));break;case"d":r+=(f&(h=parseInt(h))>0?"+":"")+h;break;case"s":r+=String(h),!1!==s&&r.length>s&&(r=r.slice(0,s));break;case"x":r+=Math.abs(parseInt(h)).toString(16);break;case"X":r+=Math.abs(parseInt(h)).toString(16).toUpperCase();break;case"f":h=parseFloat(h),!1!==s&&(h=h.toFixed(s)),r+=(f&h>0?"+":"")+h;break;case"e":h=parseFloat(h),r+=(f&(h=!1===s?h.toExponential():h.toExponential(s))>0?"+":"")+h;break;case"E":h=parseFloat(h),r+=(f&(h=!1===s?h.toExponential():h.toExponential(s))>0?"+":"")+String(h).toUpperCase();break;case"b":r+=Math.abs(parseInt(h)).toString(2);break;case"o":r+=Math.abs(parseInt(h)).toString(8);break;case"c":r=String.fromCharCode(Number(h)),!1!==s&&r.length>s&&(r=r.slice(0,s));break;case"g":var k=parseFloat(h);h=k,!1!==s&&(h=h.toFixed(s)),h=String(h),k=String(k=!1===s?k.toExponential():k.toExponential(s)),r+=(f&h>0?"+":"")+(h.length<=k.length?h:k);break;case"G":var k=parseFloat(h);h=k,!1!==s&&(h=h.toFixed(s)),h=String(h),k=String(k=!1===s?k.toExponential():k.toExponential(s)),h.length>k.length&&(h=k),r+=(f&(h=h.toUpperCase())>0?"+":"")+h;break;default:continue}0!=l&&r.length<l&&(h=b.repeat(l-r.length),$?r+=h:r=r.length&&"0"==b&&("+"==r.charAt(0)||"-"==r.charAt(0))?r.charAt(0)+h+r.slice(1):""+h+r),o+=r}}return o}; | |
// alternative _.get() fom underscore.js | |
function _get(object, path, defaultValue) { | |
var _path = Array.isArray(path) ? path : path.split('.'); | |
if (object && _path.length) return _get(object[_path.shift()], _path, defaultValue); | |
return object === undefined ? defaultValue : object; | |
}; | |
//https://stackoverflow.com/questions/47023211/better-way-to-get-property-than-using-lodash | |
function _get(object, path, defaultValue = null) { | |
if (typeof path === "string") path = path.replace(/\[/g, '.').replace(/\]/g,'').split('.'); | |
return path.reduce((xs, x) => (xs && xs[x] ? xs[x] : defaultValue), object); | |
} | |
//https://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-and-arrays-by-string-path | |
const resolvePath = (object, path, defaultValue) => path.split('.').reduce((o, p) => o ? o[p] : defaultValue, object); | |
const setPath = (object, path, value) => path.split('.').reduce((o,p,i) => o[p] = path.split('.').length === ++i ? value : o[p] || {}, object); | |
// var b={}; setPath(b,'ciccio.pasticcio', [1,2,3]); resolvePath(b,'ciccio',{}) | |
const between=(a,b)=>{ const diff=Math.abs(a.getTime() -b.getTime()); return Math.floor(diff/(3600*24*1000));} | |
// between(new Date('2021-01-01'),new Date('2021-01-28')) | |
// https://stackoverflow.com/questions/4220126/run-javascript-function-when-user-finishes-typing-instead-of-on-key-up | |
function debounce(callback, wait) { | |
let timeout; | |
return (...args) => { | |
clearTimeout(timeout); | |
timeout = setTimeout(function () { callback.apply(this, args); }, wait); | |
}; | |
} | |
const vfDBset = (key,val) => localStorage.setItem(key,JSON.stringify(val)); | |
const vfDBget = (key) => JSON.parse(localStorage.getItem(key)); | |
const vfDBdel = (key) => localStorage.removeItem(key); | |
parseJWT: function() { | |
var token = vfDBget('token'); | |
var base64Url = token.split('.')[1]; | |
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); | |
var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) { | |
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); | |
}).join('')); | |
return JSON.parse(jsonPayload); | |
}, | |
//https://forum.framework7.io/t/localization-and-how-i-solved-it/9688 | |
window.language = (vfDBget('language') || (window.navigator.language || c_default_language)).substring(0,2); | |
window.localize = (key) => _get(window.locales,`${window.language}.${key}`, key); | |
function _e(key) { return _get(window.locales,`${window.language}.${key}`, key); } | |
function _imgUsr(v){ return (v || c_usr_img ); } | |
function _tData(v) { return (new Date(v).toLocaleString(window.language,{day: "numeric"})+' <small>'+(new Date(v).toLocaleString(window.language,{month:'short',year:'numeric'}).toLocaleUpperCase())+'</small>') }; | |
function _tTime(v) { return (new Date(v).toLocaleTimeString(window.language,{timeStyle: "short"})); } | |
window.addEventListener('keyup', debounce( () => { | |
// code you would like to run 1000ms after the keyup event has stopped firing | |
// further keyup events reset the timer, as expected | |
}, 1000)) | |
const scrollToTop = () => { window.scrollTo({ top: 0, left: 0, behavior: "smooth" }); }; | |
const scrollToBottom = () => { | |
window.scrollTo({ | |
top: document.documentElement.offsetHeight, | |
left: 0, | |
behavior: "smooth", | |
}); | |
} | |
const smoothScroll = (element) => { | |
element.scrollIntoView({ | |
behavior: "smooth", | |
}); | |
}; | |
//----------------- | |
const getType = (value) => { | |
const match = Object.prototype.toString.call(value).match(/ (\w+)]/) | |
return match[1].toLocaleLowerCase() | |
} | |
getType() // undefined | |
getType({}}) // object | |
getType([]) // array | |
getType(1) // number | |
getType('fatfish') // string | |
getType(true) // boolean | |
getType(/fatfish/) // regexp | |
//----------------- | |
const isMobile = () => { | |
return !!navigator.userAgent.match( | |
/(iPhone|iPod|Android|ios|iOS|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i | |
); | |
}; | |
const setCookie = (key, value, expire) => { | |
const d = new Date(); | |
d.setDate(d.getDate() + expire); | |
document.cookie = `${key}=${value};expires=${d.toUTCString()}`; | |
}; | |
const getCookie = (key) => { | |
const cookieStr = unescape(document.cookie); | |
const arr = cookieStr.split("; "); | |
let cookieValue = ""; | |
for (let i = 0; i < arr.length; i++) { | |
const temp = arr[i].split("="); | |
if (temp[0] === key) { | |
cookieValue = temp[1]; | |
break; | |
} | |
} | |
return cookieValue; | |
}; | |
const delCookie = (key) => { | |
document.cookie = `${encodeURIComponent(key)}=;expires=${new Date()}`; | |
}; | |
const cookie = (function() { | |
var set = (name, value, seconds) => document.cookie = [name, '=', encodeURIComponent(value), seconds ? '; expires=' + new Date(new Date().getTime() + seconds * 1000).toGMTString() : '', '; path=/'].join(''); | |
var map = () => Object.fromEntries(document.cookie.split(';').map(i=>i.trim().split('='))); | |
var get = (name) => decodeURIComponent(map()[name]) || void(0); | |
var remove = (name) => set(name, '', -1); | |
return { | |
set: set, | |
get: get, | |
remove: remove, | |
map: map | |
}; | |
})(); | |
const formatMoney = (money) => money.replace(new RegExp(`(?!^)(?=(\\d{3})+${money.includes('.') ? '\\.' : '$'})`, 'g'), ','); | |
const formatMoney = (money) => money.toLocaleString(); | |
const pluck = (arr, key) => arr.map(i => i[key]); | |
const c_today = new Date(); | |
const today_yyyy_mm_dd = new Date().toLocaleDateString('fr-ca'); | |
const c_data_start = c_today.getFullYear()+'-01-01'; | |
//https://stackoverflow.com/questions/7556591/is-the-javascript-date-object-always-one-day-off | |
const c_data_end = new Date(Date.UTC(c_today.getFullYear(),c_today.getMonth(), 0)).toJSON().slice(0,10); | |
const c_data_end = new Date(new Date().getFullYear(),new Date().getMonth(),0).toLocaleDateString('fr-ca'); // yyyy-mm-dd | |
function empty(n){ return !(!!n ? typeof n === 'object' ? Array.isArray(n) ? !!n.length : !!Object.keys(n).length : true : false);} | |
const unique = (value, index, array) => array.indexOf(value) === index; ///[1,2,2,3,4,5,5,6,1].filter(unique); => [1, 2, 3, 4, 5, 6] | |
const strBetween = (str,c1='(',c2=')') => str.substring( str.indexOf(c1) + 1, str.lastIndexOf(c2)); // 'blabla(nanana)blabla' => 'nanana' | |
const htmlEscape = (str) => str?str.replace(/[&<>'"]/g,x=>'&#'+x.charCodeAt(0)+';'):''; | |
const _esc = (s) => s.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", '''); | |
const titleCase = (str) => str[0].toUpperCase() + str.slice(1).toLowerCase(); | |
const mm2in = (mm) => (Math.round(10* mm /25.4)/10).toString(); // mm to inch | |
const empty = (n) => !(!!n ? typeof n === 'object' ? Array.isArray(n) ? !!n.length : !!Object.keys(n).length : true : false); | |
const getJson = async (url) => { | |
try { | |
let response = await fetch(url,{ | |
headers: { | |
'Accept': 'application/json' | |
}); | |
let data = await response.json(); | |
return data; | |
} | |
catch(err) { | |
return {error:err} | |
} | |
}; | |
//example | |
getJson('https://jsonplaceholder.typicode.com/albums').then (j => console.log(j)); | |
const postJson = async (url,jbody) => { | |
try { | |
let response = await fetch(url,{ | |
method: 'POST', | |
body: JSON.stringify(jbody), | |
headers: { | |
'Content-type': 'application/json; charset=UTF-8', | |
} | |
}); | |
let data = await response.json(); | |
return data; | |
} | |
catch(err) { | |
return {error:err} | |
} | |
}; | |
postJson('https://jsonplaceholder.typicode.com/posts',{ | |
title: 'foo', | |
body: 'bar', | |
userId: 1, | |
}).then (j => console.log(j)); | |
const fetchJson = async (url,method,jbody) => { | |
try { | |
let response = await fetch(url,{ | |
method: method ?? 'GET', | |
body: (jbody && JSON.stringify(jbody)) ?? void(0), | |
headers: { | |
'Content-type': 'application/json; charset=UTF-8', | |
} | |
}); | |
if (!response.ok) { | |
console.log(response); | |
/* https://github.com/anonkey/http-status-code-json/blob/master/index.json | |
*/ | |
throw { | |
status: response.status, | |
error: new Error(response.statusText ?? '') | |
}; | |
} | |
let data = await response.json(); | |
return data; | |
} | |
catch(err) { | |
return (err.constructor == Object) ? err : {status:204, error: err}; | |
} | |
}; | |
fetchJson('https://jsonplaceholder.typicode.com/posts' /* ,'GET' */).then (j => console.log(j)); | |
fetchJson('https://jsonplaceholder.typicode.com/posts','POST', {title: 'foo',body: 'bar',userId: 1}).then (j => console.log(j)); | |
fetchJson('https://jsonplaceholder.typicode.com/posts/1','PUT', {title: 'fox',body: 'bay',userId: 1}).then (j => console.log(j)); | |
fetchJson('https://jsonplaceholder.typicode.com/posts/1','PATCH', {title: 'foo'}).then (j => console.log(j)); | |
fetchJson('https://jsonplaceholder.typicode.com/posts/1'','DELETE').then (j => console.log(j)); | |
fetchJson('https://httpbin.org/status/500').then (j => console.log(j)); | |
async function getData() { | |
let response = await fetch("https://jsonplaceholder.typicode.com/albums"); | |
let data = await response.json(); | |
return data; | |
} | |
getData().then(data => { | |
console.log(data); | |
}); | |
//https://medium.com/hackernoon/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9 | |
const makeRequest = async () => { | |
try { | |
// this parse may fail | |
const data = JSON.parse(await getJSON()) | |
console.log(data) | |
} catch (err) { | |
console.log(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment