VisJs How to import json data without creating duplicate edges? - json

How can I import new json data (gephiJSON) without duplicating edges in my existing data?
My code is as simple as that:
var parsed = vis.network.gephiParser.parseGephi(gephiJSON, parserOptions);
nodes.update(parsed.nodes);
edges.update(parsed.edges);
I am afraid I did not find any option or function to avoid/check duplicates.
Appreciate any help.
*I have no control over the imported data to avoid duplicates.

I use nodes.update method only to update existing network. To create new ones I use nodes.add. So, it's important to check existing data in your network before trying to add. I used a double loop routine plus a splice method for the JSON to delete duplicated nodes and edges. My code was like this (please be patient with me, I'm new in JavaScript) :
function recibedatos() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
fixedResponse = http_request.responseText;
jsonObj = JSON.parse(fixedResponse);
try {
for (var i=0;i<jsonObj.nodos.length;i++) {
for (var j=0;j<nodes.length;j++) {
if (jsonObj.nodos[i].id==nodes.get()[j].id) {
jsonObj.nodos.splice(i,1);
i-=1;
break;
}
}
}
nodes.add(jsonObj.nodos);
}
catch (err) {
alert(err);
}
try {
for (var i=0;i<jsonObj.vinculos.length;i++) {
for (var j=0;j<edges.length;j++) {
if (jsonObj.vinculos[i].to==edges.get()[j].to && jsonObj.vinculos[i].from==edges.get()[j].from && jsonObj.vinculos[i].label==edges.get()[j].label) {
jsonObj.vinculos.splice(i,1);
i-=1;
break;
}
}
}
edges.add(jsonObj.vinculos);
}
catch (err) {
alert(err);
}
} else {
alert("Ocurrio un problema con la URL.");
}
fixedResponse=null;
jsonObj=null;
}
}

Related

How to retrieve entire Logger output?

I have large sets of data (mainly arrays and objects with many elements) and I am trying to log out the entire result to check for bugs. However, in some cases it says "Logging output too large. Truncating output." Where can I see the output in its entirety? I am working with Map Objects and trying to debug why my calculations don't match Google's output.
Logger.log is limited to the number of lines that it can contain. However you can make your own logger and save it to a text file.
var Log = null;
function testLogger() {
try {
Log = new LogFile("testLogFile");
test1();
test2();
throw "done"
}
catch(err) {
Log.log(err);
Log.save();
}
}
function test1() {
Log.log("in test1");
}
function test2() {
Log.log("in test2");
}
class LogFile {
constructor (name) {
if( name === undefined ) name = "_LogFile"
this.name = name;
this.text = [];
}
log(text) {
this.text.push(text);
}
save() {
try {
let text = "";
this.text.forEach( line => text = text.concat(line,"\n") );
let files = DriveApp.getFilesByName(this.name);
let file = null;
if( files.hasNext() ) {
file = files.next();
file.setContent(text);
}
else {
DriveApp.createFile(this.name,text);
}
}
catch(err) {
Logger.log(err);
}
}
}
The text file is shown below.

Filtering json values

I have a process that returns a json object:
data={key1:[], key2:[], key3:[{key1:"a"}, {key2:"b"}], key4:[{key1:"c"}, {key2:"d"}]}
I want know if there is a simple way to filter this json object to remove the properties where the value is an empty array.
Once filtered I can then loop through the remaining properties and action the array elements.
First, we have to iterate over properties in an object.
for (var prop in data) {
if (data.hasOwnProperty(prop)) {
// Logic here
}
}
Then it's a simple check to filter out empty array properties
if (data[prop].length == 0) {
delete data[prop]
}
The full solution,
for (var prop in data) {
if (data.hasOwnProperty(prop)) {
if (data[prop].length == 0) {
delete data[prop]
}
}
}
I would prefer to create a new object that omits the empty arrays instead of deleting from the existing object.
var data={key1:[], key2:[], key3:[{key1:"a"}, {key2:"b"}], key4:[{key1:"c"}, {key2:"d"}]}
var cleanData = Object.keys(data).reduce((obj, key) => {
if (data[key] && data[key].length) {
obj[key] = data[key]
}
return obj
}, {})
Using lodash should make this pretty simple:
var filtered = _.omitBy(data, function(value) {
return Array.isArray(value) && value.length == 0;
});
You can now loop through the remaining elements in the filtered object to take further actions on them.
Try this working demo :
var data = {
key1:[],
key2:[],
key3:[
{key1:"a"},
{key2:"b"}
],
key4:[
{key1:"c"},
{key2:"d"}
]
};
for (var i in data) {
if (data[i].length == 0) {
delete data[i]
}
}
console.log(data);

store and retrieve game state using HTML5 DOM storage and JSON

I am using helper functions to store and retrieve game state using HTML5 DOM storage and the JSON features built into ECMAScript5, my code is:
function saveState(state) {
window.localStorage.setItem("gameState",state);
}
function restoreState() {
var state = window.localStorage.getItem("gameState");
if (state) {
return parse(state);
} else {
return null;
}
}
but anyhow I am not getting desired output, as i am new to JSON its hard to resolve. HELP please !
Try below code:
function saveState(state) {
window.localStorage.setItem("gameState", JSON.stringify(state));
}
function restoreState() {
var state = window.localStorage.getItem("gameState");
if (state) {
return JSON.parse(state);
} else {
return null;
}
}

How to obtain arguments.callee.caller?

I am trying to find out the name of the function that called my Google Apps Script function, by using arguments.callee.caller as in How do you find out the caller function in JavaScript?, but it seems there's no such property exported. (However, arguments.callee exists.)
How can I get that calling function's name in Google Apps Script?
As a secondary question, why isn't arguments.callee.caller there?
I made this function:
function getCaller()
{
var stack;
var ret = "";
try
{
throw new Error("Whoops!");
}
catch (e)
{
stack = e.stack;
}
finally
{
var matchArr = stack.match(/\(.*\)/g);
if (matchArr.length > 2)
{
tmp = matchArr[2];
ret = tmp.slice(1, tmp.length - 1) + "()";
}
return ret;
}
}
It throws as Error() and then gets the function name from the stack trace.
Try vary the '2' in matchArr[2] when using wrappers.
caller is a non-standard extension to JavaScript (that is, many browsers have it but it's not part of the EcmaScript standard) and not implemented in Apps Script.
I made a function to get the call stack based on jgrotius's answer:
function getCallStack()
{
var returnValue = "";
var framePattern = /\sat (.+?):(\d+) \((.+?)\)/;
try
{
throw new Error('');
}
catch (e)
{
returnValue = e.stack
.split('\n')
.filter(function(frame, index) {
return !frame.isBlank() && index > 0;
})
// at app/lib/debug:21 (getCaller)
.map(function(frame) {
var parts = frame.match(framePattern);
return {
file: parts[1],
line: parseInt(parts[2]),
func: parts[3]
};
});
}
return returnValue;
}
This is my updated version of the other two proposed solutions:
const getStacktrace = () => {
try {
throw new Error('')
} catch (exception) {
// example: at getStacktrace (helper:6:11)
const regex = /\sat (.+?) \((.+?):(\d+):(\d+)\)/
return exception
.stack
.split('\n')
.slice(1, -1)
.filter((frame, index) => {
return frame && index > 0
})
.map((frame) => {
const parts = frame.match(regex)
return {
function: parts[1],
file: parts[2],
line: parseInt(parts[3]),
column: parseInt(parts[4])
}
})
}
}
P.S.: please not that the regex has changed and also we are ignoring the first element of the stacktrace, since it is the getStacktrace function itself.

Utilities.jsonStringify and object methods

I haven't found a way yet to properly handle methods in objects when calling Utilities.jsonStringify(). Basically, I cannot use my object after I retrieve it from the CacheService and apply Utilities.jsonParse() to it.
Does anyone have a hint ?
Thanks in advance.
Marc
json does not include functions when stringifying/parsing. You have to use something homebrewn like:
function func2String(obj) {
var res={};
for (x in obj) {
var value=obj[x];
res[x]=(typeof(value)=='function')?value.toString():value;
}
return res;
}
function string2Func (obj) {
var res={};
for (x in obj) {
var value=obj[x];
if(typeof(value)!='string') {
res[x]=value;
}
else {
res[x]=(value.substring(0,9)=='\nfunction')?eval('('+value+')'):value;
}
}
return res;
}
usage:
var obj=string2Func (Utilities.jsonParse(q.diff));
var str=Utilities.jsonStringify(func2String(diff));
Of course the unpacked funcs lost all their closures.