Reading C# dictionary in Javascript - javascript

I have a dictionary variable in C# (ASP.NET). I want to send this data to Javascript. I am using this code to serialize it and send to javascript.
Dictionary<string, string> chat;
chat = new Dictionary<string, string>();
chat.Add("Sam", "How are you?");
chat.Add("Rita", "I am good");
var serialize = new System.Web.Script.Serialization.JavaScriptSerializer();
Response.Write(serialize.Serialize(chat));
On the Javascript page, I am calling this page using this;
$.ajax({
url: "TextChatCalls/getChat.aspx",
type: "POST",
context: document.body,
success: function (response) {
var Chats = response.split('\n')[0];
alert(Chats);
}
});
The value in Chats var is {"Sam":"How are you?","Rita":"I am good"}
I don't know how do I read this value in Chats. Can I anyhow convert this into a 2D array and read it as array[0][0], array[1][0] etc. ?
Thanks.
EDIT:
One more confusion is that, the response object, returned from ASP.NET, contains
{"Sam":"How are you?","Rita":"I am good"}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title></head>
<body>
<form name="form1" method="post" action="getChat.aspx?Id=141755" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZJctiKZK4rXVndR3mbGssIarCrOF" />
</div>
<div>
</div>
</form>
</body>
</html>
And not just {"Sam":"How are you?","Rita":"I am good"} as expected. And hence I have to split the response object by var Chats = response.split('\n')[0]; which makes it an string!

You read like this:
alert(Chats["Sam"]);
(so like a C# Dictionary :-). You read/write to it using something like Chats["propertyName"])
or, to go through each value:
for (var c in Chats)
{
if (Chats.hasOwnProperty(c))
{
alert(c + ' ' + Chats[c]);
}
}
Note that this is different than C#. In C# c would contain a KeyValuePair<> containing both the key and the value. In Javascript c is only the key and to get the value you have to use Chats[c].
(the reasoning for hasOwnProperty is here http://yuiblog.com/blog/2006/09/26/for-in-intrigue/)
Now... If you really want to split it:
var array = [];
for (var c in Chats)
{
if (Chats.hasOwnProperty(c))
{
array.push([c, Chats[c]]);
}
}

Just add the data type json to your ajax request
$.ajax({
url: "TextChatCalls/getChat.aspx",
type: "POST",
dataType: "json"
context: document.body,
success: function (response) {
// do something with response
});
This will make response a javascript object that you can access like this
alert(response["sam"]) //How are you?
to split that up into a 2d array just do this
var Chats = [];
for ( k in response ){
Chats[Chats.length] = [k, response[k]];
}

I guess the important point here is that you properly understand what is going on on the JavaScript client side. The datatype that arrives on the JavaScript client side is a JSON string. JSON (= JavaScript Object Notation) can directly be interpreted by JavaScript.
A JavaScript object looks as follows:
var anObject = { name: "Sam", surname: "abc"};
You can access the properties of a JavaScript object either through a somewhat Dictionary-similar way like
anObject["name"] //will get "Sam"
or directly (property notation)
anObject.name
Instead a similar JSON string would look like
var aJsonString = '{ "name": "Sam", "surname": "abc"}'
Now to convert the JSON string to a JavaScript object you need to parse it. jQuery does this already for you, otherwise you can invoke JSON.parse(aJsonString) and you'll get a valid JavaScript object.
Here I did a quick example: http://jsbin.com/adejev/2/edit

For ASP.NET Core, I used this inside the cshtml file. Basically I rebuilt the entire Dictionary into Javascript. The reason for this approach is because I have subfunctions in Javascript that won't be able to call the server model functions with dynamic parameters on events like keypress.
var ModelZxcvWarnLookup = {};
#foreach (var kvp in Model.View.ZxcvbnWarningMsgLocalization)
{
#:ModelZxcvWarnLookup['#Html.Raw(#kvp.Key)'] = '#Html.Raw(#kvp.Value)';
}
Inspecting the html page fetched by the browser:
var ModelZxcvWarnLookup = {};
ModelZxcvWarnLookup["Straight rows of keys are easy to guess"] = "Chinese Straight rows of keys are easy to guess";
ModelZxcvWarnLookup["Short keyboard patterns are easy to guess"] = "Chinese Short keyboard patterns are easy to guess";
ModelZxcvWarnLookup['Repeats like "aaa" are easy to guess'] = 'Repeats like "aaa" are easy to guess';

Related

How can I encode JSON objects to pass from Google Appscript over its HTML interface?

Google Appscript has the ability to pass things from the server side scripting, to client side html.
eg
appscript.gs
var htmlServ = HtmlService.createTemplateFromFile("addDetailsBookingForm");
let order_id = getSheetOrderID(sheet); //let order_id = "98";
htmlServ.order = pullOrderStore(order_id) // let's say this is an array
const html = htmlServ.evaluate();
html.setWidth(850).setHeight(450);
const ui = SpreadsheetApp.getUi();
ui.showModalDialog(html, "form");
What I'd like to do is pass JSON across using this interface. However, objects are not supported from what I can understand. I can send strings, arrays but not objects.
However, it seems to me that I could turn a JSON object into a string, before sending it, and then parse it client side and turn it back into an object again.
Taking some inspiration from here, I was wondering if one could do something like
var htmlServ = HtmlService.createTemplateFromFile("addDetailsBookingForm");
let order_id = "98";
orderDetailsObject = pullFromWordPressOrder(order_id)
htmlServ.orderDetailsObject = JSON.stringify(orderDetailsObject)
Logger.log(htmlServ.orderDetailsObject)
<etc>
displayjsonfile.html
<script>
// this will output orderDetailsObject from the server side into orderDetailsObject on the client side. Despite the name, they're totally different variables.
var orderDetailsObject = <?=orderDetailsObject?>;
var product_object = JSON.parse(orderDetailsObject);
console.log(product_object)
var order_id = product_object.id //ToTest
example JSON
{"id":98,"parent_id":0,"status":"pending","currency":"GBP","version":"6.5.1","prices_include_tax":false,"date_created":"2022-08-11T20:12:58","date_modified":"2022-08-12T13:07:32","discount_total":"0.00","discount_tax":"0.00","shipping_total":"0.00","shipping_tax":"0.00","cart_tax":"0.00","total":"30.00","total_tax":"0.00","customer_id":17,"order_key":"wc_order_f368FMstESsXn","billing":{"first_name":"Freddie","last_name":"Flintoff","company":"","address_1":"a place","address_2":"","city":"a town","state":"derby","postcode":"sk13 7rx","country":"","email":"freddie#example.com","phone":"01234123123"},"shipping":{"first_name":"Freddie","last_name":"Flintoff","company":"","address_1":"a place","address_2":"","city":"a town","state":"derby","postcode":"sk13 7rx","country":"","phone":""},"payment_method":"","payment_method_title":"","transaction_id":"","customer_ip_address":"94.118.139.237","customer_user_agent":"","created_via":"admin","customer_note":"","date_completed":null,"date_paid":"2022-08-11T20:13:46","cart_hash":"","number":"98","meta_data":[{"id":1441,"key":"_new_order_email_sent","value":"true"},{"id":1442,"key":"_automatewoo_order_created","value":"1"}],"line_items":[{"id":50,"name":"Tim's Bike shed","product_id":75,"variation_id":0,"quantity":1,"tax_class":"","subtotal":"30.00","subtotal_tax":"0.00","total":"30.00","total_tax":"0.00","taxes":[],"meta_data":[],"sku":"","price":30,"parent_name":null}],"tax_lines":[],"shipping_lines":[],"fee_lines":[],"coupon_lines":[],"refunds":[],"payment_url":"https://dev1.example.com/checkout/order-pay/98/?pay_for_order=true&key=wc_order_f368FMstESsXn","date_created_gmt":"2022-08-11T20:12:58","date_modified_gmt":"2022-08-12T13:07:32","date_completed_gmt":null,"date_paid_gmt":"2022-08-11T20:13:46","currency_symbol":"£","_links":{"self":[{"href":"https://dev1.example.com/wp-json/wc/v3/orders/98"}],"collection":[{"href":"https://dev1.example.com/wp-json/wc/v3/orders"}],"customer":[{"href":"https://dev1.example.com/wp-json/wc/v3/customers/17"}]}}
Currently the JSON object outputs in the html as
var orderDetailsObject = '{\x22id\x22:98,\x22parent_id\x22:0,\x22status\x22:\x22pending\x22,\x22currency\x22:\x22GBP\x22,\x22version\x22:\x226.5.1\x22,\x22prices_include_tax\x22:false,\x22date_created\x22:\x222022-08-11T20:12:58\x22,\x22date_modified\x22:\x222022-08-12T13:07:32\x22,\x22discount_total\x22:\x220.00\x22,\x22discount_tax\x22:\x220.00\x22,\x22shipping_total\x22:\x220.00\x22,\x22shipping_tax\x22:\x220.00\x22,\x22cart_tax\x22:\x220.00\x22,\x22total\x22:\x2230.00\x22,\x22total_tax\x22:\x220.00\x22,\x22customer_id\x22:17,\x22order_key\x22:\x22wc_order_f368FMstESsXn\x22,\x22billing\x22:{\x22first_name\x22:\x22Freddie\x22,\x22last_name\x22:\x22Flintoff\x22,\x22company\x22:\x22\x22,\x22address_1\x22:\x22a place\x22,\x22address_2\x22:\x22\x22,\x22city\x22:\x22a town\x22,\x22state\x22:\x22derby\x22,\x22postcode\x22:\x22sk13 7rx\x22,\x22country\x22:\x22\x22,\x22email\x22:\x22freddie#example.com\x22,\x22phone\x22:\x2201234123123\x22},\x22shipping\x22:{\x22first_name\x22:\x22Freddie\x22,\x22last_name\x22:\x22Flintoff\x22,\x22company\x22:\x22\x22,\x22address_1\x22:\x22a place\x22,\x22address_2\x22:\x22\x22,\x22city\x22:\x22a town\x22,\x22state\x22:\x22derby\x22,\x22postcode\x22:\x22sk13 7rx\x22,\x22country\x22:\x22\x22,\x22phone\x22:\x22\x22},\x22payment_method\x22:\x22\x22,\x22payment_method_title\x22:\x22\x22,\x22transaction_id\x22:\x22\x22,\x22customer_ip_address\x22:\x2294.118.139.237\x22,\x22customer_user_agent\x22:\x22\x22,\x22created_via\x22:\x22admin\x22,\x22customer_note\x22:\x22\x22,\x22date_completed\x22:null,\x22date_paid\x22:\x222022-08-11T20:13:46\x22,\x22cart_hash\x22:\x22\x22,\x22number\x22:\x2298\x22,\x22meta_data\x22:[{\x22id\x22:1441,\x22key\x22:\x22_new_order_email_sent\x22,\x22value\x22:\x22true\x22},{\x22id\x22:1442,\x22key\x22:\x22_automatewoo_order_created\x22,\x22value\x22:\x221\x22}],\x22line_items\x22:[{\x22id\x22:50,\x22name\x22:\x22Tim\x27s Bike shed\x22,\x22product_id\x22:75,\x22variation_id\x22:0,\x22quantity\x22:1,\x22tax_class\x22:\x22\x22,\x22subtotal\x22:\x2230.00\x22,\x22subtotal_tax\x22:\x220.00\x22,\x22total\x22:\x2230.00\x22,\x22total_tax\x22:\x220.00\x22,\x22taxes\x22:[],\x22meta_data\x22:[],\x22sku\x22:\x22\x22,\x22price\x22:30,\x22parent_name\x22:null}],\x22tax_lines\x22:[],\x22shipping_lines\x22:[],\x22fee_lines\x22:[],\x22coupon_lines\x22:[],\x22refunds\x22:[],\x22payment_url\x22:\x22https:\/\/dev1.example.com\/checkout\/order-pay\/98\/?pay_for_order=true\x26key=wc_order_f368FMstESsXn\x22,\x22date_created_gmt\x22:\x222022-08-11T20:12:58\x22,\x22date_modified_gmt\x22:\x222022-08-12T13:07:32\x22,\x22date_completed_gmt\x22:null,\x22date_paid_gmt\x22:\x222022-08-11T20:13:46\x22,\x22currency_symbol\x22:\x22£\x22,\x22_links\x22:{\x22self\x22:[{\x22href\x22:\x22https:\/\/dev1.example.com\/wp-json\/wc\/v3\/orders\/98\x22}],\x22collection\x22:[{\x22href\x22:\x22https:\/\/dev1.example.com\/wp-json\/wc\/v3\/orders\x22}],\x22customer\x22:[{\x22href\x22:\x22https:\/\/dev1.example.com\/wp-json\/wc\/v3\/customers\/17\x22}]}}';
Clearly - it's being encoded/decoded poorly - specifically speech marks are coming out encoded.
Is this expected - or is there a better way to do this?
To be clear - it works, but it feels like it isn't pretty... not to mention not best practice.
Here is an example of how to pass a JSON object to the client.
Code.gs
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
function showTest() {
var myObject = { name: "MyTest", value: 100 };
var html = HtmlService.createTemplateFromFile("HTML_Test");
html.myObject = JSON.stringify(myObject);
SpreadsheetApp.getUi().showModalDialog(html.evaluate(),"Test");
}
HTML_Test.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<input id="name" type="text">
<br>
<input id="value" type="text">
<script>
var myObject = <?= myObject ?>;
(function() {
myObject = JSON.parse(myObject);
document.getElementById("name").value = myObject.name;
document.getElementById("value").value = myObject.value;
})();
</script>
</body>
</html>
Screenshot
Here's a reference the parameters and return values that can cause problem where passing objects with google.script.run.
The date has got me in the past. If you have a date in a cell and the cell is formatted to display it as a string, the use getDisplayValues() and pass it as a string and then use new Date() constructor to return it back to a date on the server side.
Other than that pretty much any object will work that can be stringified.

How do I read a 2D array from jQuery in a Java Servlet?

I want to send arbitrarily complex array data to a Java servlet, but have no idea how to read it on the servlet side. Here is the client side:
var data = {
name : 'Jack',
age : 30,
info : [ [1,2] , [3,4] , [5,6] ],
info2: [1,2,3]
}
$.ajax({
url: someURL,
data: data,
success: function(resp) { console.log(resp); }
});
I know I can use JSON.stringify and then parse it out on the server side, but for the sake of this question, I can't change the front end code. How do I read the "info" variable on the server side using the HttpServletRequest object? I also know you can do something like this for single arrays:
String[] info2 = request.getParameterValues("info2[]");
But this doesn't work with 2D arrays or more complicated arrays.
Any ideas?
If info is known to be a fixed-length array
private static final int INFO_LEN = 3;
You can collect its values inside your servlet as
String[][] info = new String[INFO_LEN][];
for (int i = 0; i < info.length; i++) {
info[i] = request.getParameterValues("info["+i+"][]");
}
If the length is not known beforehand, collect the values in a loop until you get a null.

How can I pass a JavaScript array through AJAX to a Perl script?

How can I create a Perl array from a JavaScript array that is passed via AJAX?
Perl Access:
#searchType = $cgi->param('searchType');
print #searchType[0];
Output:
employee,admin,users,accounts
It seems that the Perl array sets the first value (#searchType[0]) as a string of all the passed JavaScript array objects.
It is an old question, so I am not sure whether that is still interesting for you but maybe someone else is interested in this question, too.
As already suggested in the comments above, one way to pass a javascript array to Perl via ajax is to convert this array first to an JSON object - using "JSON.stringify(jsArray);" - which is then decoded in the Perl script. I added a very simple example below where the first item of your array is returned through an alert.
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Testing ajax</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#test").click(function(){
var jsArray = ["employee", "admin", "users", "accounts"];
var jsArrayJson = JSON.stringify(jsArray);
$.ajax({
type: 'POST',
url: '/cgi-bin/ajax/stackCGI/processJsArray.pl', //change the path
data: { 'searchType': jsArrayJson},
success: function(res) {alert(res);},
error: function() {alert("did not work");}
});
})
})
</script>
</head>
<body>
<button id="test" >Push</button>
</body>
</html>
processJsArray.pl
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use JSON;
my $q = CGI->new;
my #myJsArray = #{decode_json($q->param('searchType'))}; #read the json object in as an array
print $q->header('text/plain;charset=UTF-8');
print "first item:"."\n";
print $myJsArray[0]."\n";
You need to express it in the form of key=value&key=other-value.
var searchType = ["employee", "admin", "users", "accounts"];
var keyName = "searchType";
for (var i = 0; i < searchType.length; i++) {
searchType[i] = encodeURIComponent(keyName) + "=" + encodeURIComponent(searchType[i]);
}
var queryString = searchType.join("&");
Then you use the queryString as part of your URL or post data as normal.

Javascript Object literal, POST problems

Im trying to get autocomplete-rails.js working in Rails with Ajax,
i Have the following function
<script type="text/javascript">
function reply_click(clicked_id)
{
var x = "work";
var y = "monday"
alert(y)
$.ajax({
type : 'POST',
url : "/whens",
data: { y : x},
success : function(data) {
alert(data);
},
});
}
</script>
The problem im getting is that this returns
"y"=>"work"
and i want it to return the value of y instead
"monday"=>"work"
Also, if i do the following
<script type="text/javascript">
function reply_click(clicked_id)
{
var x = "work";
var y = "monday"
var data = {};
data[x] = y;
$.ajax({
type : 'POST',
url : "/whens",
data,
success : function(data) {
alert(data);
},
});
}
</script>
it seems to return The problem im getting is that this returns
"term"=>"work"
Any idea how i can get it returning the contents of y
If a key doesn't have quotes, that doesn't mean it's using a variable.
The correct way of doing it, as you mention is
var data = {};
data[y] = x;
$.ajax({
type : 'POST',
url : "/whens",
data : data,
success : function(data) {
alert(data);
},
});
Note I changed it to data[y] = x;
if u want to load some data using ajax which in return can be used for auto-complete then load the array of strings by ajax.
eg.
in controller do-
def get_characteristics
unless ['Threads', 'Note'].include?(params[:name])
#characteristics = Category.all.collect(&:characteristic)
respond_to do |format|
format.js{}
end
end
in get_characteristics.js.haml (eg is in haml)
var characteristics = #{#characteristics.to_json};
$('#characteristic').autocomplete( //the id of the text fields where u want autocomplete
source: characteristics //the array of string that u want for autocomplete
)
for additional info http://jqueryui.com/demos/autocomplete/
variable as index in an associative array - Javascript
> var x = "work"
> var y = "monday"
> data= {}
{}
> data[x]=y
'monday'
> data
{ work: 'monday' }
You can't, the second snippet (data[y] =) is the only way. Here's why:
An object literal, like all things in JS is an object (duh) and has properties. All variables declared in the global scope are properties of the global (nameless) object. The only (semi-)true variables you have are the ones you declare in a closure scope. So looking at it from that viewpoint, it stands to reason that properties should not be quoted when constructing an object literal. I'd even go as far as to say that allowing quoted properties in the declaration of an object literal should be considered wrong, or it should -at the very least- be discouraged.
JS is a wonderful language, covered up by a pile of inconsistencies, quirks and bad ideas. Sadly, if all you know is the gunk (almost everybody knows the gunk, few know the actual language and where it gets its power) the rare features that are consistent and good look like an obstacle at first. Thankfully, you have tons of constructs that enable you to do just what you want, and do it well.
In this case, you could just write it all out data[a] = b; data[c] = d;... OR you could use a power-constructor (google it)
An other option is just a very small loop, assuming your data object will be filled using the arguments passed to the function:
var data = {};
var argArray = Array.prototype.slice.apply(arguments,[0]);//returns array of arguments
var duo;
while(duo = argArray.splice(0,2))
{
data[duo[0]] = duo[1];
if (argArray.length < 2)
{
break;
}
}
just to give an example. I'd recommend you (and everyone else) to look into crockfords constructions when it comes to objects, and what a function call entails in JS: a function isn't just called, a call-object is created.

Parse XML into Javascript Object

I am grabbing data from a Google spreadsheet through the Google API using cURL in PHP. Using a AJAX HTTP request (via jQuery) I can pull all the data in and get it into an array, but since the <content> tag looks like dirty JSON I'm a little stuck.
I would like to be able to reference the data as a JS object, like so:
alert(xml.feed.content.name);
Example Code:
$.ajax({
type: "GET",
url: GtargetURL,
dataType: "xml",
success: function parseMyXML(xml){
var Entries = new Array;
var i = 0;
$(xml).find("entry").each(function(){
var content = $(this).find("content").text();
Entries[i]=content;
i++;
});
var myArray= new Array();
myArray= Entries[1].split(",");
alert (myArray[1]); // Result: "test2"
}
});
Example XML:
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:gsx=
<entry>
<content type='text'>relativeid: 4, name: test2, type: teset3, multiples: yes, cat: yes</content>
</entry>
<entry>many more entries...</entry>
</feed>
Thanks for any help you can offer.
For what it's worth, I am using this URL format for the Google api call:
https://spreadsheets.google.com/feeds/list/KEY-ID-HERE/1/public/basic
I know that I can do a "cell" call instead of a "list" call, but this suits my purposes better.
You could do something like this: http://jsfiddle.net/GVUnF/ http://jsfiddle.net/rMMkD/1/ in your loop.
var jsonLikeString = "name:red, type:blue, multiples:green, cat:brown";
var jsObject = {};
var stringWithoutSpaces = jsonLikeString.split(' ').join('');
var splitStrings = stringWithoutSpaces.split(",");
var kvPairArray = [];
for(var i in splitStrings){
if(splitStrings.hasOwnProperty(i)){
var kvPair = splitStrings[i];
kvPairArray = kvPair.split(":");
jsObject[kvPairArray[0]] = kvPairArray[1];
}
}
alert(jsObject.cat);
Please note that
var foo = new Array;
is not exactly idiomatic in javascript.
You should use
var foo = [];
instead.
Also, for appending to an array you should use
foo.push('something');
instead of having a variable i and incrementing it every loop.
There are two parts to your question:
How to turn XML into JSON
How to turn some text in XML that is almost JSON into JSON
To make XML into JSON you can use a library like http://www.thomasfrank.se/xml_to_json.html
It turns
<animals>
     <dog>
          <name>Rufus</name>
          <breed>labrador</breed>
     </dog>
     <dog>
          <name>Marty</name>
          <breed>whippet</breed>
     </dog>
     <cat name="Matilda"/>
</animals>
Into
{"animals":
{"dog":[
{"name":"Rufus",
"breed":"labrador"},
{"name":"Marty",
"breed":"whippet"}],
"cat":
{"name":"Matilda"}}}
Then you can follow the suggestion from TheShellfishMeme to turn
relativeid: 4, name: test2, type: teset3, multiples: yes, cat: yes
Into a JSON object

Categories