Possible memory leak in apps script array? - javascript

I'm building a Google Docs add on that pulls data from Jira.
The response object (issueMeta in the code below) is a JSON nested array with > 500,000 lines in it. The response object exists. I filter thru it to find an object with type.name === "Epic", which I've verified exists in the response data.
However on the last line I'm getting "TypeError: Cannot read property 'fields' of undefined", so it sounds like epicFields is not being set in the filter function.
I'm wondering if its a memory leak issue. Any ideas?
const issueMeta = getIssueMeta();
let epicFields = issueMeta.filter(function (type) {
return type.name === "Epic"
});
epicFields = epicFields[0].fields;

Related

Array of Objects from JSON acting differently than array of objects created locally

I've been going through Wes Bos' Javascript30 course, and have been messing with JSON and arrays.
I'm trying to figure out what's happening here.
I have a simple JSON test file that I'm fetching and pushing into an array, and an identical array created locally. When I try to console.log the name of the first person with the local array, it works fine. But when I try to console.log the name of the first person in the JSON fetched array, I get an error "Uncaught TypeError: Cannot read property 'name' of undefined"
JSON file:
[
{
"name":"Sean",
"Age":"23"
},
{
"name":"kev",
"Age":"23"
}
]
javascript:
const people = [];
const peopleLocal = [ {"name":"Sean", "age":"23"}, {"name":"kev",
"age":"23"}];
const endpoint = "test.json";
fetch(endpoint)
.then(blob => blob.json())
.then(data => people.push(...data));
console.log(people);
console.log(peopleLocal);
console.log(peopleLocal[0].name);
console.log(people[0].name);
console.log(people) and console.log(peopleLocal) returns the same array of objects. Then console.log(peopleLocal[0].name) returns "Sean". But console.log((people[0].name) returns the undefined error mentioned above. Why?
They are not acting differently at all, you are just printing the name way before the asynchronous fetch finishes. Try printing it the right time, namely in the calback where you receive the response, like this:
const people = [];
const peopleLocal = [ {"name":"Sean", "age":"23"}, {"name":"kev",
"age":"23"}];
const endpoint = "test.json";
fetch(endpoint)
.then(blob => blob.json())
.then(data => {
people.push(...data);
console.log(people);
console.log(people[0].name);
});
console.log(peopleLocal);
console.log(peopleLocal[0].name);
But how come console.log(people) works outside of the callback, but
not console.log(people[0].name)?
Good question. The developer console's object browser actually stores the reference to the object, not a copy of it, so when you look at it on the console, you see the latest values, not the ones at the time of being printed.
See this SO answer:
console.log() shows the changed value of a variable before the value actually changes

Ionic 2 and JSON Data Addition

I am working with Ionic 2 Storage to persist form data. I save the data like this:
this.storage.set(key, JSON.stringify(formData));
And I retrieve and attempt to update the data like this:
this.getReport(key).then((report) => {
var objReport = JSON.parse(report);
objReport.push(data); //this is the problem
this.storage.set(pk, JSON.stringify(objReport));
});
getReport is just this:
getReport(key) {
return this.storage.get(key);
}
So I know that .push is for arrays and not objects, but I don't think its efficient to do all this conversions because I am dealing with large objects.
My question is: what is the most efficient way to retrieve json from storage and append to it? It makes no sense to me that .parse returns an object if objects do not have a push method like arrays.
Here is the error:
Runtime Error Uncaught (in promise): TypeError: Cannot read property
'push' of undefined TypeError: Cannot read property 'push' of
undefined
what this error means is that, there are no records for that key at this moment.
So, you would have to do a check like this :
this.getReport(key).then((report) => {
var objReport = [];//initialise empty Array
if(report){ //if there is a record in that key location
objReport = JSON.parse(report); //parse the record & overwrite objReport
}
objReport.push(data); //Now this push will happen regardless of report or not
this.storage.set(pk, JSON.stringify(objReport));
});

stringify object array to JSON Selectively

I have an Object array named users.
The object format in this array looks like this:
var userExample = {pub:{name:'John', id:'100'}, priv:{location:'NYC', phone:'000000'}};
As a restful service, clients may request information of all users.
And obviously I just want to send public information to them.
So I want to serialize my data selectively by keys(priv key will be ignored)
Here is my code snippet:
var users = [];
function censor(key, value) {
if (key == priv) {
return undefined;
}
return value;
}
app.get('/listUsers', function(req, res){
res.end(JSON.stringify(users, censor));
});
When I run these code, an error occurred:
ReferenceError: priv is not defined
I'm a Javascript beginner, please help.
Change priv to "priv".
But your approach is dangerous. In similar conditions I usually create a new object to export and I explicitly copy the properties which should be exported, this way there's no risk of leak on future data structure changes. A white list is always more future proof than a black list.
Newer versions of JSON.stringify() have a replacer array
E.g.
```
JSON.stringify(foo, ['week', 'month']);
// '{"week":45,"month":7}', only keep "week" and "month" properties
```
Try with:
if (key == "priv")
This should work.

How to parse returned css information using Selenium webdriver.executescript

Newbie to Javascript in Node environment...
Using this code below where the script is getting css values for a particular web element, how do I parse this in javascript?
driver.executeScript(script, ele).then(p => {
console.log(p);
})
The code above shows this result in the console.
{ class: 'container ng-scope', 'ng-controller': 'CalcCtrl' }
It's returned as type Object, so I can't figure out for example how to get the value of the key "class"...
If I change the code to this:
driver.executeScript(script, ele).then(p => {
console.log(p);
var obj = JSON.parse(p);
console.log(obj.class);
})
I get this error...
Where column 27 is the parse in JSON.parse...
The answer to this question, is this:
driver.executeScript(script, ele).then(p => {
if(p.class) console.log(p.class);
})
JavaScript returns undefined for any key in a JSON object that cannot be found, therefore, the If(p.class) ensures this item of data has a key named class and prints it out.

cannot read property 'push' of null

I have a page which works on my localhost.. when I put t on a remote server, it gave an error. the code which returns the error is
var $app_list = localStorage.getItem('LsAppList');
var AppListJson = JSON.parse($app_list);
AppListJson.push({
"extapp_id": appdetail.get("addAppId"),
"desc": appdetail.get("addAppName"),
"device_no": appdetail.get("devicenoValue"),
"validation_key": appdetail.get("activationkeyValue")
});
the console log is
Uncaught TypeError: Cannot read property 'push' of null
addToJson EncigoHome.js:126
n.extend.trigger kendo.mobile.min.js:9
s.extend._release kendo.mobile.min.js:15
i._userEvents.o.UserEvents.tap kendo.mobile.min.js:15
n.extend.trigger kendo.mobile.min.js:9
l.extend.notify kendo.mobile.min.js:13
u.extend._trigger kendo.mobile.min.js:13
u.extend.end kendo.mobile.min.js:13
l.extend._eachTouch kendo.mobile.min.js:13
l.extend._end kendo.mobile.min.js:13
arguments.length.t.(anonymous function) kendo.mobile.min.js:10
b.event.dispatch jquery-1.9.1.js:9593
v.handle
localStorage is per domain (more specifically same origin). The localStorage associated with the remote domain does not have access to the values stored in the localStorage associated with your localhost.
You should check to see if there is a stored value and fallback to a default one or treat the error:
var $app_list = localStorage.getItem('LsAppList');
var AppListJson = $app_list != null ? JSON.parse($app_list) : [];
//...
More verbose:
var $app_list = localStorage.getItem('LsAppList'),
AppListJson;
if ($app_list != null) {
AppListJson = JSON.parse($app_list);
} else {
// treat no LsAppList stored case
// you could show a message or set it to a default value
AppListJson = [];
}
This "no previously stored data" scenario will happen whenever the user clears his browser data or switches browsers/devices as well, so it must be treated properly.
The root cause of the error, as you've probably figured out already, is that localStorage.getItem(key) returns null when no value is stored for the given key in the current domain. Then JSON.parse(null) === null and null.push() throws.
Just as a nitpick, I'd suggest reviewing your variables naming:
Don't use PascalCase naming for non-constructors.
Don't mix camelCase with underline naming conventions.
Recommended read: Idiomatic.js naming.
And also, AppListJson is not JSON, it is a native array. JSON can only exist in string context, that is, your $app_list is JSON. More in-depth explanation about JSON/not JSON: There's no such thing as a "JSON Object"
The .push() method can only be used on arrays.
It seems that you don't have the item stored in localStorage, which is why it is returning null

Categories