I am working with the org.graalvm.polyglot script engine in my Java11 project to evaluate a JavaScript.
The script to be evaluated returns a JavaScript array with two entries.
...
var result={};
result.isValid=false;
result.errorMessage = new Array();
result.errorMessage[0]='Somehing go wrong!';
result.errorMessage[1]='Somehingelse go wrong!';
....
In my java code I try to evaluate the result object:
Value resultValue = context.getBindings(languageId).getMember("result");
In my Eclipse Debugger I can see that I receive a PolyglotMap containing the expected values:
I can iterate over that map to get the values with a code like this:
...
try {
mapResult = resultValue.as(Map.class);
} catch (ClassCastException | IllegalStateException | PolyglotException e) {
logger.warning("Unable to convert result object");
return null;
}
Iterator it = mapResult.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
String itemName = pair.getKey().toString();
Object itemObject = pair.getValue();
...
In this way I am able to extract the boolean 'isValid'. But with the object 'errorMessage' I struggle.
Inspecting the Object again within the Eclipse Debugger it looks like this:
If I test this object it is an instanceOf Map. But I am unable to get any of the values out of this object.
Can anybody help me to understand what exactly this object represents and how I can extract the both values 'Someting go wrong!' and 'Sometingelse go wrong!' ?
When I iterate over this second map it seems to be empty - even if the debugger shows me the correct values.
I'm not 100% sure why as(Map.class) behaves that way, it might be worth creating an issue on github to figure it out: github.com/oracle/graal
But if you access the values using the API without converting to a Map it would work as you expect:
var errorMessage = resultValue.getMember("errorMessage");
errorMessage.hasArrayElements(); // true
var _0th = errorMessage.getArrayElement(0);
var _1th = errorMessage.getArrayElement(1);
You can also convert the polyglotMap to Value and then do it:
val errorMessage = context.asValue(itemObject);
errorMessage.hasArrayElements(); // true
errorMessage.getArrayElement(0);
PolyglotMap of course has the get method. And the Value javadoc says that:
Map.class is supported if the value has Value.hasHashEntries() hash entries}, members or array elements. The returned map can be safely cast to Map. For value with members the key type is String. For value with array elements the key type is Long.
Can you try getting them with the Long keys?
There might be something obvious I'm missing, so in any case it's better to raise an issue on GitHub.
I am storing two items in sessionStorage, an integer and a string array. I can see the items in Chrome Dev Console (Application - sessionStorage) and they are correct.
The values as it shows now in the Chrome Dev Console are:
HTTP_Index 4
HTTP_History ["Start","text_14","text_7","text_10"]
In a javascript function, I retrieve them from sessionStorage:
var HTTP_Index = sessionStorage.getItem(HTTP_Index);
var HTTP_History = sessionStorage.getItem(HTTP_History);
p_Index = JSON.parse(HTTP_Index);
p_History = JSON.parse(HTTP_History);
I decrement the index:
p_Index = p_Index - 1;
console.log("HTTP_Index Now " + p_Index);
and the log shows that the value is now 3.
Next I store the value p_Index back to sessionStorage:
sessionStorage.setItem("HTTP_Index", JSON.stringify({ "p_Index" });
Whether I enclose p_Index in quotes or not, the dev console now shows the function as "undefined."
Next I tried to do it like this:
sessionStorage.setItem("HTTP_Index", JSON.stringify({ "p_Index" });
but same problem. So finally I tried this:
var obj = { HTTP_Index: p_Index };
var objJSON = JSON.stringify(obj);
sessionStorage.setItem(objJSON);
But the Chrome dev console shows:
Uncaught TypeError: Failed to execute 'setItem' on 'Storage': 2 arguments required, but only 1 present.
What am I doing wrong in using JSON.stringify for sessionStorage.setItem?
Thanks for any help.
When using .setItem you must set a key, and then the value you want to store.
In the case of your first example, you're doing this but have made a simple typo. Also you want to stringify the contents in p_Index, not the string "p_index", so, you need to remove your quotes around it when stringifying:
sessionStorage.setItem("HTTP_Index", JSON.stringify(p_Index)); // <-- missing this closing bracket
And so you'll get a syntax error here.
In the case of your second example (attempt), you're not using valid syntax as you're setting an object with no value.
In your third example, you're trying to set the value to be the stringified object (so your value is just the string, not the object), and so you're not specifying a key. To do this you can use:
var objJSON = JSON.stringify(p_index);
sessionStorage.setItem("HTTP_Index", objJSON);
In your latest example:
var obj = { HTTP_Index: p_Index };
var objJSON = JSON.stringify(obj);
sessionStorage.setItem(objJSON);
sessionStorage.setItem first argument must be the key which you want to set and the 2nd is the data which you are going to store.
So you miss the key/name.
I have an array with 4 elements and in one scenario I want to pop one element from the array. But after pop array gives the same result as before.
I have checked in the console window and there I have find a different behavior like array length is 4 and it shows like it has 5 elements.
I have tried to remove the empty elements also but still the same issue is coming .
var brudcrumbDataArray=JSON.parse(brudcrumbDataString);
brudcrumbDataArray = brudcrumbDataArray.filter(function(n){ return n != undefined });
console.log(brudcrumbDataArray)
brudcrumbDataArray.pop();
console.log(brudcrumbDataArray)
Her is the array :
[{"name":"Dashboard","url":"","path":"","class":"icon-home2 position-left","type":"MainMenu","queryParams":""},{"name":"Main","url":"#/dashboard","path":"/dashboard","class":"","type":"SubMenu","queryParams":""},{"name":"Sub Accounts","url":"#/account/customers","path":"/account/customers","class":"","type":"SubMenu","queryParams":""},{"name":"End Users","url":"#/account/endusers","path":"/account/endusers","class":"","type":"SubMenu","queryParams":""},{"name":"Profile","url":"#/user-dashboard","path":"/user-dashboard","class":"","type":"SubMenu","queryParams":""}]
After pop also array gives the same data and same length. Can someone help me to solve this issue ?
Snippet, check your console to see the problem:
var brudcrumbDataString =`[{"name":"Dashboard","url":"","path":"","class":"icon-home2 position-left","type":"MainMenu","queryParams":""},{"name":"Main","url":"#/dashboard","path":"/dashboard","class":"","type":"SubMenu","queryParams":""},{"name":"Sub Accounts","url":"#/account/customers","path":"/account/customers","class":"","type":"SubMenu","queryParams":""},{"name":"End Users","url":"#/account/endusers","path":"/account/endusers","class":"","type":"SubMenu","queryParams":""},{"name":"Profile","url":"#/user-dashboard","path":"/user-dashboard","class":"","type":"SubMenu","queryParams":""}]`;
var brudcrumbDataArray=JSON.parse(brudcrumbDataString);
brudcrumbDataArray = brudcrumbDataArray.filter(function(n){ return n != undefined });
console.log(brudcrumbDataArray)
brudcrumbDataArray.pop();
console.log(brudcrumbDataArray)
A result on the console seems to be correct. Both the logs on the console window are showing the result after the operation. Why is the first log showing a result in it? because, in javascript, complex objects get stored by reference, that's why your first log does show a result in it too.
Store by reference? what does it mean? : https://docstore.mik.ua/orelly/webprog/jscript/ch04_04.htm
Try below one,
var brudcrumbDataString =`[{"name":"Dashboard","url":"","path":"","class":"icon-home2 position-left","type":"MainMenu","queryParams":""},{"name":"Main","url":"#/dashboard","path":"/dashboard","class":"","type":"SubMenu","queryParams":""},{"name":"Sub Accounts","url":"#/account/customers","path":"/account/customers","class":"","type":"SubMenu","queryParams":""},{"name":"End Users","url":"#/account/endusers","path":"/account/endusers","class":"","type":"SubMenu","queryParams":""},{"name":"Profile","url":"#/user-dashboard","path":"/user-dashboard","class":"","type":"SubMenu","queryParams":""}]`;
var brudcrumbDataArray=JSON.parse(brudcrumbDataString);
brudcrumbDataArray = brudcrumbDataArray.filter(function(n){ return n != undefined });
console.log(JSON.parse(JSON.stringify(brudcrumbDataArray)))
brudcrumbDataArray.pop();
console.log(JSON.parse(JSON.stringify(brudcrumbDataArray)))
Look closely here, we are doing deep data copy with using JSON operations, by surrounding object in JSON.parse(JSON.stringify( )) and it won't point to reference anymore now.
And log will be more clear as below,
it showing because the reference to the same object so when you pop last element the object get modified and shows the length as 4 so the first consoled object also get updated.
var brudcrumbDataArray = [{"name":"Dashboard","url":"","path":"","class":"icon-home2 position-left","type":"MainMenu","queryParams":""},{"name":"Main","url":"#/dashboard","path":"/dashboard","class":"","type":"SubMenu","queryParams":""},{"name":"Sub Accounts","url":"#/account/customers","path":"/account/customers","class":"","type":"SubMenu","queryParams":""},{"name":"End Users","url":"#/account/endusers","path":"/account/endusers","class":"","type":"SubMenu","queryParams":""},{"name":"Profile","url":"#/user-dashboard","path":"/user-dashboard","class":"","type":"SubMenu","queryParams":""}]
//var brudcrumbDataArray=JSON.parse(brudcrumbDataString);
var newBrudcrumbDataArray = brudcrumbDataArray.filter(function(n){ return n != undefined });
console.log(brudcrumbDataArray)
newBrudcrumbDataArray.pop();
console.log(newBrudcrumbDataArray)
I'm having problems why my .split() function.
somehow when i splay my line the first [0] element in the array can be accessed but the 2nd [1] can't
I have the following string:
,{"relationID":"000001","recID":"1d2712eb-4f08-4b4f-b6e9-600c9631b503"
And the code below is how i try to split this (tempArray contains a x number of strings like the above):
var templine = tempArray[i].substr(1, tempArray[i].length);
//alert(templine);
var line = templine.split(',');
var s1 = line[0].split('"')[3];
var s2 = line[1].split('"')[3];
when i use alert(s1) or alert(s2) i do get the value however, the folowing error always occurs on the last line (var s2):
caught TypeError: Cannot read property 'split' of undefined
this causes the rest of my script to crash and it won't finish what it's supposed to, displaying an empty page.
My question, what is going wrong here? why does s1 function properly and s2 which is exactly the same except for the index of the line array crash my script.
I want to emphasise when i use the alert function to check the value of my variable s1 and s2 they do contain the right value.
EDIT:
maybe a nice bonus since there might be an easyer way.
after I've gotten the values s1 and s2 i want to put them in a map like so:
map[s2] = s1;
as you can probably tell the string i use is the result of splitting 1 humongous string on ('}'). the code displayed here is what i do when looping trough this array.
That can only be caused by a attempt to access element on the array that is really undefined. Probably your input is not what you are expecting.
Check if line.length > 1 before you try to read those indexes of the array.
As it seems to be a JSON, may be you should try to parse the JSON, it would make your code more readable and reliable. Check JSON.parse browser compatibility before using it (IE8+).
For example:
var data = JSON.parse('{ "field1": "value1", "field2": "value2" }');
var s1 = data['field1'];
var s2 = data['field2'];
Hope I've helped.
not a js expert so this might be a stupid question but...
Why does the log show that the array has changed? I was expecting the array still to be a [0,0] since the method is invoked after the console.log. Also, if I try to replace the whole array like this:
this.my_array = [1,0];
the log will still show [0,0], which is something that makes more sense to me.
What's going on?
function Y() {
this.my_array = [0,0];
this.changeIt = function() {
this.my_array[0] = 1;
};
}
var z = new Y;
console.log(z.my_array);
z.changeIt();
In some browsers (Chrome, for instance) console.log displays a live, interactive display of your array, not a point-in-time snapshot. So if you're looking at the console after this runs, it's been updated because of the change. Chrome also does slightly different things when you use console.log interactively in the console panel than when you use it from within a script.
You'll see what you're expecting if you display a string instead:
var z = new Y;
console.log(z.my_array.join(", "));
z.changeIt();
That shows the point-in-time snapshot you're expecting.
It works for me: http://jsfiddle.net/LyhgW/
Edit: The fact that i'm using alert makes this code work. This works around Chrome's live-feature in the console and displays a snapshot instead.