everybody. I've just integrated duktape in my c++ code so that I'm able to use javascript.
But the problem I can't solve right now : how to use json objects in javascript.
Assume I've got some javascript like
function hi(person) {
print ('hi, ' + person.name );
}
And json object :
{
'name' : 'duktape'
}
So now I need to call function hi with an argument of this json in my cpp code.
duk_eval_string(ctx, "function hi(person) {print ('hi, ' + person.name );}");
duk_push_global_object(ctx);
duk_get_prop_string(ctx, -1, "hi" ); // pushes function from loaded script to stack
auto json = "{'name' : 'duktape' }";
duk_push_string(ctx, json);
duk_pcall(ctx, 1);
The output I get tells, that object is not correct
hi, undefined
Would like to head any suggestions on who should be done to get it working! Thank's for your time :)
You need to use duk_json_decode:
char *json = "{\"name\": \"duktape\"}";
duk_push_string(ctx, json);
duk_json_decode(ctx, -1);
duk_pcall(ctx, 1);
duk_pop_2(ctx);
Output:
hi, duktape
Note that your original json is not valid, you need to use " as string delimiters instead of '.
Depending on what you really needs, you could also create the object manually:
duk_idx_t obj_idx = duk_push_object(ctx);
duk_push_string(ctx, "duktape");
duk_put_prop_string(ctx, obj_idx, "name");
duk_pcall(ctx, 1);
duk_pop(ctx);
Related
Line break in javascipt string console
console.log("Foo" + "\n" + "Bar");
Line break in javascript object console
console.log({ value : "Foo\nBar" });
Is it possible to add linebreaks in javascript objects.
The answer is no: when you print an object to the console log, strings will be written as javascript objects (similar but not identical to what you'd get if you explicitly converted them into JSON, like console.log(JSON.stringify(object))).
If you want for some reason to print your strings with line breaks, you'd have to implement the object-to-string conversion yourself; perhaps with something like this:
function customString(object) {
let string = '{\n';
Object.keys(object).forEach(key => {
string += ' "' + key + '": "' + object[key] + '"\n';
});
string += '}';
return string;
}
console.log(customString({ value: "Foo\nBar" }));
(It sounds like you have an idea in mind of exactly how you want this output to look, so adjust the function above until it works as expected.)
You can make JSON pretty with automatic line breaks using:
console.log(JSON.stringify({ test: { key: { inner: 'val' } }}, null , 2))
Where 2 is the number of spaces/indent for each level.
You can use ES6:
console.log(`hello
world`)
will produce:
hello
world
I think its originally creating a line break, but due to the object, it's not showing directly. Try to assign it in variable and access that in the console.
Code:
var v = {val:"test\ntest"};
console.log(v.val);
Output:
test
test
I am trying to load a javascript in WebView to do some calculations and get the output in a string. I tried to use following code
string htmlFragment = "<html><head><script type='text/javascript'>" +
"function doubleIt(incoming){ " +
" var intIncoming = parseInt(incoming, 10);" +
" var doubled = intIncoming * 2;" +
" document.body.style.fontSize= doubled.toString() + 'px';" +
" return doubled.toString());" +
"};" +
"</script></head><body>" +
"<div id = 'myDiv'>I AM CONTENT</div></body></html>";
htmlView.NavigateToString(htmlFragment);
htmlView.LoadCompleted += async(s1,e1) =>
{
string result = await htmlView.InvokeScriptAsync("eval", new string[] { "doubleIt(25)" });
Debug.WriteLine(result);
};
Update
I am able to load simple javascript easily now based on help provided in the answer. But now I am facing issues when there is more than one function in javascript, I am getting an exception. I am trying the following code
string htmlFragment = #"<html><head><script type='text/javascript'>" +
"function a(){return 10;};" +
"function b(){return 20;};" +
"function c(){return 30;};" +
"return (a()*b()*c());" +
"</script></head><body>" +
"<div id = 'myDiv'>I AM CONTENT</div></body></html>";
Please suggest.
The documentation for this feature is really poor. It took me some time to figure out how to invoke Javascript in UWP WebView
When you first look at the function call webView.InvokeScriptAsync(string,string[]) your initial reaction is that they want the function name as the first parameter and then the function paramaeters as the string array. (mainly because the MSDN documentation says this)
Parameters
scriptName
Type: System.String [.NET] | Platform::String [C++]
The name of the script function to invoke.
arguments
Type: System.String[]
[.NET] | Platform::Array [C++]
A string array that
packages arguments to the script function.
HOWEVER, this is wrong and will lead to hours of head banging. REALLY, what they want is the word "eval" in the first parameter and then a string array of functions, and or commands you wish to eval
var value = await webViewer.InvokeScriptAsync("eval",
new string[]
{
"functionName(functionParams)"
});
Having worked with Microsoft APIs for a few years now I am convinced that this is not the intended way of consuming this function and is a bit of a hack. Unfortunately if you want to consume JavaScript this is the only way that I know that works currently.
Anthony,
Try to check your own suggestion:
await webViewer.InvokeScriptAsync("eval",
new string[]
{
"functionName(functionParams)"
});
or:
await webViewer.InvokeScriptAsync(functionName, new string[]{ functionParameters });
The same as Microsoft suggests, just you are limiting a function name by one ("eval") - not necessary. Trust me, you can use any function name, as I am now with UWP and before with windows phone hybrid apps.
The question is already 4 years old, but I'm coming to see why you were getting an empty string as a result.
In your example, the functions in JavaScript return integers while the expected value is of type string.
By modifying these functions and returning a string like this:
string htmlFragment = #"<html><head><script type='text/javascript'>" +
"function a(){return '10';};" +
"function b(){return '20';};" +
"function c(){return '30';};" +
"</script></head><body>" +
"<div id = 'myDiv'>I AM CONTENT</div></body></html>";
We get the good result on the way back.
I have a webservice that returns a JSON object, but when I try to loop through it, each item in each object returns undefined
Here is the JSON object returned from the webservice
[{"result":14,"question":"6 - 7 مرات اسبوعيا","aID":70},{"result":29,"question":"3 - 5 مرات اسبوعيا","aID":71},{"result":41,"question":"مرة واحدة اسبوعيا","aID":72},{"result":14,"question":"1 - 3 مرات شهريا","aID":73}]
and here how I loop through it:
var resultAsJson = data.d;
$.each(resultAsJson, function (index, resObject) {
$('#pollResults').append('<p><strong>' + resObject.result + ' ' +
resObject.question + '</strong></p>');
alert(resObject.question);
});
------------------
UPDATE
------------------
hi Guys,
the above code worked fine, the problem was the JSON response that I returned from the webservice was serialized as the following:
Dim m_result As New Data.Objects.ObjectParameter("Result", GetType(Boolean))
Dim lstofresult As List(Of addPollvote_Result) = Context.addPollvote(para_pid, para_aid, Date.Now, m_UID, Nothing, HttpContext.Current.Request.ServerVariables("REMOTE_ADDR"), Nothing, m_result).ToList
Dim m_json As New Script.Serialization.JavaScriptSerializer
Return m_json.Serialize(lstofresult)
When I removed the serialization and just returned the list, it worked perfect, see the below working code.
Dim m_result As New Data.Objects.ObjectParameter("Result", GetType(Boolean))
Dim lstofresult As List(Of addPollvote_Result) = Context.addPollvote(para_pid, para_aid, Date.Now, m_UID, Nothing, HttpContext.Current.Request.ServerVariables("REMOTE_ADDR"), Nothing, m_result).ToList
Return lstofresult
and it worked perfect.
Make sure resultAsJson is actually a JSON object and not a string and it should work (see this jsfiddle) - use resultAsJson = JSON.parse(resultAsJson) to do the conversion from string to json object .
Give this a go. I assume you're using jQuery:
// The JSON String from the web service
var jsonString = '[{"result":14,"question":"6 - 7 مرات اسبوعيا","aID":70},{"result":29,"question":"3 - 5 مرات اسبوعيا","aID":71},{"result":41,"question":"مرة واحدة اسبوعيا","aID":72},{"result":14,"question":"1 - 3 مرات شهريا","aID":73}]';
// Parse the JSON string into a JS object
var jsonObj = JSON.parse(jsonString);
// Loop through, and pull what you need from it
$(jsonObj).each(function() {
console.log(this.result + " " + this.question);
});
The problem seems to be your datasource.
I would use a 'for' loop for testing purposes:
var resultAsJson = data.d;
var resultAsJsonLength = resultAsJson.length;
for(i=0;i<resultAsJsonLength;i++) {
$('#pollResults').append('<p><strong>' + resultAsJson[i].result + ' ' +
resultAsJson[i].question + '</strong></p>');
alert(resultAsJson[i].question);
}
You're going to have to provide more information about how you're accessing the data, which seems to be the foundation of your problem...
I have Converted a C# class in Json Object after it I stringify that json Object then it converts with backslash(escaping character) and when i used following code to read the json string it gives me undefined message in alert .
<script>
var jsString = { "JsonString": ["{\"reachoutid\":1,\"user_ID\":1,\"question\":\"Best CMS in Microsoft .Net\",\"anonymous\":false,\"shared\":false,\"create_date\":\"\\/Date(-62135596800000)\\/\",\"update_date\":\"\\/Date(1327300086183)\\/\",\"status\":0,\"start_date\":\"\\/Date(-62135596800000)\\/\",\"end_Date\":\"\\/Date(-62135596800000)\\/\",\"reachoutfactorsList\":null,\"reachoutchoicesList\":[{\"reachoutid\":0,\"choice_ID\":4,\"orders\":0,\"description\":\"Sitecore\",\"preachOutID\":0,\"pchoice_ID\":4,\"porders\":0,\"pdescription\":\"Sitecore\"},{\"reachoutid\":0,\"choice_ID\":5,\"orders\":0,\"description\":\".Net Nuke \",\"preachOutID\":0,\"pchoice_ID\":5,\"porders\":0,\"pdescription\":\".Net Nuke \"},{\"reachoutid\":0,\"choice_ID\":6,\"orders\":0,\"description\":\"Drupal\",\"preachOutID\":0,\"pchoice_ID\":6,\"porders\":0,\"pdescription\":\"Drupal\"}],\"detail\":\"Write more text to check progress bar work properly.\",\"set_Listof_Tags\":null,\"tag\":null,\"get_Listof_Tags\":null,\"userstatus\":null,\"actType\":\"RO\"}"], "_getList_MyActivities": null, "_getList_MyPeersActivities": null, "userID": 1 }
for (i = 0; jsString.JsonString.length > i; i++)
{
alert(jsString.JsonString[i].reachoutid);
//"Giving Undefined Message "
}
</script>
Your JSON is stored as a string, not as a native object. To convert it back, change your alert( ... ) line to use JSON.parse( ... ) like this:
alert( JSON.parse(jsString.JsonString[i]).reachoutid )
Your JSON shouldn't be quoted. When it is, JS interprets is as a string instead of an object
var jsObject = { "JsonString": [{"reachoutid":1,"user_ID":1,"question":"Best CMS in Microsoft .Net","anonymous":false,"shared":false}]} // etc.
I have a json like:
{"156644":{ "name":"name1",
"street":"street1",
"city":"city1"
"68656":{ "name":"name2 ",
"street":"street2",
"city":"city1"
"388655":{ "name":"name3",
"street":"street3",
"city":"city1"
"4564":{ "name":"name4",
"street":"street4",
"city":"city1"
"6333":{ "name":"name5",
"street":"street5",
"city":"city1"}}
Now I want to decode this json. In my Javascript I wrote:
var object = eval(obj_json);
if(typeof(object)!="undefined"){
//fuel
for (var ii=0; ii<object.length; ii++){
alert(ii)
}
}
Now I get an Undefined error at object.length. So I tried to parse my json like:
var object = eval(' (' + obj_json + ') '); alert(object.length);
but this doesn't work at all.
Now I get an "missing ] after element list" error.
Can U help me? PLZ!
You're missing closing brackets after each element:
{"156644":{ "name":"name1",
"street":"street1",
"city":"city1" // Bracket needs to be here!
"68656":{ "name":"name2 ",
"street":"street2",
"city":"city1" // Bracket needs to be here!
// ...
Instead, it should probably look like:
{"156644":{ "name":"name1",
"street":"street1",
"city":"city1"},
"68656":{ "name":"name2 ",
"street":"street2",
"city":"city1"},
// ...
You're missing closing } thingies all over the place. Didn't you mean this:
{"156644":{ "name":"name1",
"street":"street1",
"city":"city1" }, // THIS, RIGHT HERE
"68656":{ "name":"name2 ",
"street":"street2",
"city":"city1" }, // AND THIS
"388655":{ "name":"name3",
"street":"street3",
"city":"city1" }, // AND THIS
"4564":{ "name":"name4",
"street":"street4",
"city":"city1" }, // AND THIS
"6333":{ "name":"name5",
"street":"street5",
"city":"city1"}}
If that is an exact dump of your JSON, then your problem is with your var names;
Your JSON provider needs to change their output, or you need to parse it before you try to decode it, to get proper var names in there:
json=eval( obj_json.replace( /([, \n\r\t])([0-9]*):/g, '$1"v_$2":' ) );
(not rigorously tested, just an example that works on the example code)
Taking out any suggestions as to the problem, as the OP's two postings have different content. But still recommending JSONLint.
Btw: I fixed this Problem by coding:
eval("var jsonobject=" + obj_json);
now it works! Now I can write:
for(ii in jsonobject){
var intii = parseInt(ii);
if (!isNaN(intii)){
var street = jsonobject[ii].street;
alert(street)
}
}