Skip to content

Instantly share code, notes, and snippets.

@AnderssonPeter
Last active November 28, 2022 07:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save AnderssonPeter/54f99b92f4d7f07adf5d450b22644a66 to your computer and use it in GitHub Desktop.
Save AnderssonPeter/54f99b92f4d7f07adf5d450b22644a66 to your computer and use it in GitHub Desktop.
Javascript debugging tools
Contains the following javascript tools:
Break when property changes
Break when property changes (works on arrays)
Save object as json to disk
Dumpt cookies to console
Flatten javascript array
Flatten recusrive object
Get recusrive parent
Group array by property
Sort orbject
Sorted json stringify
function breakOn (obj, propertyName, mode, func) {
// this is directly from https://github.com/paulmillr/es6-shim
function getPropertyDescriptor(obj, name) {
var property = Object.getOwnPropertyDescriptor(obj, name);
var proto = Object.getPrototypeOf(obj);
while (property === undefined && proto !== null) {
property = Object.getOwnPropertyDescriptor(proto, name);
proto = Object.getPrototypeOf(proto);
}
return property;
}
function verifyNotWritable() {
if (mode !== 'read')
throw "This property is not writable, so only possible mode is 'read'.";
}
var enabled = true;
var originalProperty = getPropertyDescriptor(obj, propertyName);
var newProperty = { enumerable: originalProperty.enumerable };
// write
if (originalProperty.set) {// accessor property
newProperty.set = function(val) {
if(enabled && (!func || func && func(val)))
debugger;
originalProperty.set.call(this, val);
}
} else if (originalProperty.writable) {// value property
newProperty.set = function(val) {
if(enabled && (!func || func && func(val)))
debugger;
originalProperty.value = val;
}
} else {
verifyNotWritable();
}
// read
newProperty.get = function(val) {
if(enabled && mode === 'read' && (!func || func && func(val)))
debugger;
return originalProperty.get ? originalProperty.get.call(this, val) : originalProperty.value;
}
Object.defineProperty(obj, propertyName, newProperty);
return {
disable: function() {
enabled = false;
},
enable: function() {
enabled = true;
}
};
};
"BreakOn has been loaded, does not work on arrays, please specify breakOn(object, 'property', [optional]function(newValue) { return true/false; });"
function breakOn(obj, propertyName, func) {
if (propertyName) {
var enabled = true;
var arrayChangeHandler = {
get: function(target, property) {
return target[property];
},
set: function(target, property, value, receiver) {
if (enabled && (!func || func && func(value)))
debugger;
target[property] = value;
// you have to return true to accept the changes
return true;
}
};
obj[propertyName] = new Proxy(obj[propertyName], arrayChangeHandler);
return {
disable: function() {
enabled = false;
},
enable: function() {
enabled = true;
}
};
}
else {
var arrayChangeHandler = {
get: function(target, property) {
return target[property];
},
set: function(target, property, value, receiver) {
if (!func || func && func(value))
debugger;
target[property] = value;
// you have to return true to accept the changes
return true;
}
};
return new Proxy(obj, arrayChangeHandler);
}
}
"BreakOn has been loaded, does work on arrays, please specify breakOn(object, 'property', [optional]function(newValue) { return true/false; });"
function flatten(xs, childSelector) {
return xs.reduce((acc, x) => {
acc = acc.concat(x);
let children = childSelector(x);
if (children) {
acc = acc.concat(flatten(children, childSelector));
x.items = [];
}
return acc;
}, []);
}
"flatten(data, x => x.items)"
function flatten(xs, childSelector) {
return xs.reduce((acc, x) => {
acc = acc.concat(x);
let children = childSelector(x);
if (children) {
acc = acc.concat(flatten(children, childSelector));
}
return acc;
}, []);
}
"Used to flatten recusrive objects flatten(data, x => x.items)"
var getRecursiveParent = function (item, field, predicate) {
var parent = item[field];
if (!parent) {
return undefined;
}
if (predicate(parent)) {
return parent;
}
return getRecursiveParent(parent, field, predicate);
};
"Used to get a specific parent recursively getRecursiveParent(node, 'parent', x => x.type === \'test\')"
var groupBy = function (arr, keySelector, valueSelector) {
function isFunction(functionToCheck) {
return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}
return arr.reduce(function(rv, x) {
let key = isFunction(keySelector) ? keySelector(x) : x[keySelector];
let value = valueSelector ? (isFunction(valueSelector) ? valueSelector(x) : x[valueSelector]) : x;
(rv[key] = rv[key] || []).push(value);
return rv;
}, {});
}
"groupBy([{ key: 1, value: 2 }, { key: 2, value: 3 }], \"key\", \"value\")\n\rgroupBy([{ key: 1, value: 2 }, { key: 2, value: 3 }], x => x.key, x => x.value)"
(function(console){
console.save = function(data, filename){
if(!data) {
console.error('Console.save: No data')
return;
}
if(!filename) filename = 'console.json'
if(typeof data === "object"){
data = JSON.stringify(data, undefined, 4)
}
var blob = new Blob([data], {type: 'text/json'}),
e = document.createEvent('MouseEvents'),
a = document.createElement('a')
a.download = filename
a.href = window.URL.createObjectURL(blob)
a.dataset.downloadurl = ['text/json', a.download, a.href].join(':')
e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
a.dispatchEvent(e)
}
})(console)
"Use console.save(object) to save a object as json to a file"
//Sök igenom ett object
var searchObject = function (object, matchCallback, ignorePaths, maxDepth, depth, currentPath, result, searched)
{
if (depth === undefined)
{
depth = 0;
}
ignorePaths = ignorePaths || [];
if (maxDepth !== undefined && depth === maxDepth)
{
return;
}
currentPath = currentPath || '';
result = result || [];
searched = searched || [];
if (searched.indexOf(object) !== -1 && object === Object(object))
{
console.log('Circular reference detected', object);
return;
}
searched.push(object);
if (matchCallback(object))
{
result.push(
{
path: currentPath,
value: object,
parents: searched.length > 1 ? searched.slice(0, searched.length - 1) : []
}
);
}
try
{
if (object === Object(object))
{
for (var property in object)
{
if (property.indexOf("$") !== 0)
{
//if (Object.prototype.hasOwnProperty.call(object, property)) {
const innerPath = currentPath + (Array.isArray(object) ? "[" + property + "]" : (currentPath !== '' ? "." : '') + property);
if (ignorePaths.some(x => innerPath.startsWith(x)))
{
continue;
}
searchObject(object[property], matchCallback, ignorePaths, maxDepth, depth + 1, innerPath, result, searched);
//}
}
}
}
}
catch (e)
{
console.log(object);
throw e;
}
searched.splice(searched.indexOf(object), 1);
return result;
}
"searchObject($scope.arende, x => x && x.kontrollerad, [optional] ignorePaths, [optional] maxDepth);"
function sortObject(obj, arraySorter) {
if (!obj)
return obj;
if(typeof obj !== 'object')
return obj
if (Array.isArray(obj)) {
if (arraySorter) {
obj.sort(arraySorter);
}
for (var i = 0; i < obj.length; i++) {
obj[i] = sortObject(obj[i], arraySorter);
}
return obj;
}
var temp = {};
var keys = [];
for(var key in obj)
keys.push(key);
keys.sort();
for(var index in keys)
temp[keys[index]] = sortObject(obj[keys[index]], arraySorter);
return temp;
}
function sortedStringify(obj, arraySorter) {
var temp = angular.copy(obj);
temp = sortObject(temp, arraySorter);
return JSON.stringify(temp);
}
"sortedStringify(doc, (i1, i2) => i1.id - i2.id | i1.kod - i2.kod | i1.name - i2.name | i1.namn - i2.namn | i1 - i2);"
function sortObject(obj, arraySorter) {
if(typeof obj !== 'object')
return obj
if (Array.isArray(obj)) {
if (arraySorter) {
obj.sort(arraySorter);
}
for (var i = 0; i < obj.length; i++) {
obj[i] = sortObject(obj[i], arraySorter);
}
return obj;
}
var temp = {};
var keys = [];
for(var key in obj)
keys.push(key);
keys.sort();
for(var index in keys)
temp[keys[index]] = sortObject(obj[keys[index]], arraySorter);
return temp;
}
"sortObject(rootObject, (item1, item2) => item1-item2);"
// viewcookies.js
// https://github.com/bgrins/devtools-snippets
// Shows all cookies stored in document.cookies in a console.table
(function() {
'use strict';
window.viewCookies = function() {
if (document.cookie) {
const cookies = document.cookie
.split(/; ?/)
.map(s => {
const [ , key, value ] = s.match(/^(.*?)=(.*)$/);
return {
key,
value: decodeURIComponent(value)
};
});
console.table(cookies);
}
else {
console.warn('document.cookie is empty!');
}
};
})();
window.viewCookies();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment