What String format is acceptable to append to this JSON output? - javascript

I have an existing "blackbox" web service. I need to append a session ID to the end of that output so that Javascript and similar clients can resume the stateful session.
Given the output below, what is the correct syntax to append or prepend an arbitrary GUID, so that it can be properly deserialized as valid JSON?
Note This data below is perfect. If I can somehow add a "removable" bit of information, using JSON.NET the string GUID, that would be ideal.
Output from REST call
"{\"sa\":[\"BHDQ9TLPeaeVuSSgXv9bsOIVFUWbOpivMKhGki7YPLzIXEyHuxRAZhDgts2sEcBQpLBuKJZCtcmSlzWZ9iK0AAA=\",\"BAhyo7T0Wq1WBLXnyN4vo1L94rWLhCCv4DqROi+p9XHO6UeS0Gw6xh1JAKOtXBU2fA432LkNqng8cUt1eAX0bqs=\",\"BGFmyTreWY5pICAcf3itoqbfhs5brOmIDLNF3V7p7slPYdCSVhwWUT5mHD6Lb5kNi\/Qy9tracNUtVgvo3f51FrI=\",\"BMV7RIwoz+LdFgD2fq7UZ7E88KFq\/03381NDYFIKYgUKxEzuXoj6hZfSB0slX5fdaL44Lf6i\/UjDzPQt2XUG8NE=\",\"BL8BnU5WvFn7vIlKi14dWsqykNf1\/nmE55YXFGwLx9Qu3VvDblULt\/U8CXPI1vD8+wMXCRnkunXqxlsFqgghf8w=\"],\"sb\":[\"BInTtgTAn\/zkmrkporhV5DvPZRq5YWm8e\/m02oq55UfY3RxIhOplJgwLjgKMHKYDthYEBcqNNNuVbbWnbtKVAqA=\",\"BJbh5y95wHGjmAPDFNqgewnBxtqVke0sloDD2S3IdrWZ95JfP77rtXZ4lTG8g9PuTLJbl4exZUnM16260WxJ9wU=\",\"BKevE9i2J8CicXHX3elCoQPEpTOmJyGOlBskIbFMFGQFhJ5TD7N1221rhhH9HY6DsfRojmefozsQYzo7Pokp+Hg=\",\"BJbVTRyh8WwCxfR7jRXnran4td7k5+vEfM+HWxeAibneSjdMRQ1Fg6QxKLu+Zu1aPdXqD8M29kABOTAiYopVuQE=\",\"BFv3alDqjo7ckdB2vuxJ15Gur1xsgATjLe9drt\/XU9AkbN+AELCv+mF1Xy8+83L2A1p8aGxF4b7dsrMed27u1j4=\"],\"sz\":\"BF1IiqMz0KmT4gZN6euJquWFt2UmVjyOEdaX0jH8uQMAPG8DBoyneT2PJ9NQTE2xBOP9TtAb1d2O+iCojFqzkvI=\"}"
The output above comes from Chrome. I'm not sure if Chrome adds additional quotes, etc but when I debug System.String on the server, I see the same thing being sent to the WCF service.
The end-usage for this will be a Chrome and Firefox plug in

Well if I am correctly understanding:
You get JSON from a blackbox service. It contains some properties and values. You want to add a new property with some GUID and send it to browser.
If this is correct, try following:
var json=<WHAT YOU GET FROM SERVICE>;
var converter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, converter);
obj.sid="this is the new session id"; //ADD NEW PROPERTY
var j=JsonConvert.SerializeObject(obj); //GET BACK JSON STRING WITH NEW PROPERTY
Of if you just want to add session id on client side (inside your plugin) the utilize JSON2 javascript library and use following code (as also suggested by Josh in comments):
var o = JSON.parse(<REST OUTPUT>);
o.sid = <YOUR SESSION ID>;
To convert back to JSON string.
var jsn = JSON.stringify(o);

There is no way to modify that particular response without breaking existing clients. If you can break existing clients, or if you are working with clients that you control, you could wrap the object in another object, setting two keys: GUID and data. For example:
var json = JsonConvert.SerializeObject(new {
data = foo,
GUID = bar,
});
Where bar is the GUID that you want to use, and foo is one of two things:
The JSON string from the response. This will result in the final object looking like so:
{
data: "{\"sa\":[\"BHDQ9TLPeaeVuSSgXv9bsOIVFUWbOpivMKhGki7YPLzIXEyHuxRAZhDgts2sEcBQpLBuKJZCtcmSlzWZ9iK0AAA=\",\"BAhyo7T0Wq1WBLXnyN4vo1L94rWLhCCv4DqROi+p9XHO6UeS0Gw6xh1JAKOtXBU2fA432LkNqng8cUt1eAX0bqs=\",\"BGFmyTreWY5pICAcf3itoqbfhs5brOmIDLNF3V7p7slPYdCSVhwWUT5mHD6Lb5kNi\/Qy9tracNUtVgvo3f51FrI=\",\"BMV7RIwoz+LdFgD2fq7UZ7E88KFq\/03381NDYFIKYgUKxEzuXoj6hZfSB0slX5fdaL44Lf6i\/UjDzPQt2XUG8NE=\",\"BL8BnU5WvFn7vIlKi14dWsqykNf1\/nmE55YXFGwLx9Qu3VvDblULt\/U8CXPI1vD8+wMXCRnkunXqxlsFqgghf8w=\"],\"sb\":[\"BInTtgTAn\/zkmrkporhV5DvPZRq5YWm8e\/m02oq55UfY3RxIhOplJgwLjgKMHKYDthYEBcqNNNuVbbWnbtKVAqA=\",\"BJbh5y95wHGjmAPDFNqgewnBxtqVke0sloDD2S3IdrWZ95JfP77rtXZ4lTG8g9PuTLJbl4exZUnM16260WxJ9wU=\",\"BKevE9i2J8CicXHX3elCoQPEpTOmJyGOlBskIbFMFGQFhJ5TD7N1221rhhH9HY6DsfRojmefozsQYzo7Pokp+Hg=\",\"BJbVTRyh8WwCxfR7jRXnran4td7k5+vEfM+HWxeAibneSjdMRQ1Fg6QxKLu+Zu1aPdXqD8M29kABOTAiYopVuQE=\",\"BFv3alDqjo7ckdB2vuxJ15Gur1xsgATjLe9drt\/XU9AkbN+AELCv+mF1Xy8+83L2A1p8aGxF4b7dsrMed27u1j4=\"],\"sz\":\"BF1IiqMz0KmT4gZN6euJquWFt2UmVjyOEdaX0jH8uQMAPG8DBoyneT2PJ9NQTE2xBOP9TtAb1d2O+iCojFqzkvI=\"}",
guid: "00000000-0000-0000-0000-000000000000"
}
And you would get at the data through two calls to JSON.parse (or the equivalent).
The deserialized object from the JSON response. This will result in the final object looking like so (most data removed for brevity sake):
{
data: {
sa: [],
sb: [],
sz: ""
},
guid: "00000000-0000-0000-0000-000000000000"
}
And you would access data through response.data.
Why any modification can break existing clients
Where the current response is an object, there are only a few ways to modify it:
Injecting a key into the object. This assumes that no client uses Object.keys() or in any way iterates the key set (e.g. for (k in obj)). While this may be true, this is an assumption.
Adding another object to the end: }, {. Doing so would require that the response be transformed into an array:
[{}, {}]
This would break any client that is assumes the response is an object.
Wrapping the current response in a surrounding object (as proposed above). This as well breaks any clients that assumes a certain structure for the response.
{data:{}, guid: ""}

Related

How to pass an array of objects through a query string according to REST?

What is the best practice to pass an array of objects throught query string in REST style?
For example, the array:
examples[] = [
{
name: "foo",
value: "1"
},
{
name: "bar",
value: "2"
}
]
I thought about it:
/items?examples[0][name]=foo&examples[0][value]=1&examples[1}[name]=bar&examples[1][value]=2
Are there other ways to do this?
Upd:
I need readable URL to show it to the user in the address field. It should display state of some filters in the table, I'm not sending it to the backend.
Since you're parsing this manually in JS, you could keep the structure you have and just write a parsing function
var items = {};
location.search.split("?")[1].split("&").map((q) => {
var [token, value] = q.split("="),
[idx, key] = /\[([0-9+])\]\[(\w+)\]/g.exec(token).slice(1, 3);
if (!items[idx]){
items[idx] = {};
}
items[idx][key] = value;
})
This will yield you something with a structure like
{
"0": {
"key1": "data"
"key2": "data:
},
"1": {
"key1": "data"
"key2": "data"
}
}
If you need it to end up an array, it would be pretty easy to convert, but keeping it as an object with numeric strings for keys will prevent an error if it's not sequential.
Also, note there's no error checking or anything here, so if you're going to have query string params that aren't in that format, you'll want to test for that and handle them differently.
You shouldn't take care about how pass data for a backend, Angular do it for you.
About your example, you probably want to update or save several item. So it's not into the url that you will pass your data but into the Request Body :
this.httpService.post(yourUrl, examples, yourHttpOptions).subscribe( (response) => {
// you manage your response data
});
REST does not care how you encode information into your identifiers. You can use any scheme you want, so long as it is consistent with the production rules defined by RFC 3986.
REST cares a little bit about how you share information about creating URI, in the sense that that information should be shared in some readily standardizable form, like an HTML form, or a URI Template.
We don't, to my knowledge, have a "readily standardizable form" that describes how to transform a json array to a query string.
But... REST does allow code on demand; embedding, for example, a bunch of java script into a resource where that javascript knows how to encode the json into the URI... that is in bounds, so long as you have the code on demand itself referenced in a readily standardizable way (like we have with HTML and script tags).
In practice? urlencode the json representation and put it onto the query string directly. That will get you through until you start to discover the real requirements that your URI design needs to support (requirements like: operators needing to be able to understand the access logs).

How can I create an object or array of array data in JS with key named elements?

I have an array called values. At present, I'm appending new data to this array as such:
values.push(guests);
The result of my array is something like this:
["123456789", "Joe", "Bloggs", "Test Corp", "fiji", true, "guest, guest 2, guest 3", true]
I have now realised that in its present state this data is useless to me as I cannot tell what each element is. In my example above, the first long number is an account number and the second element is a first name but these are liable to change. E.g the company name Test Corp may not always exist in the data. This means I cannot use the numerical key [3] to target it because it may not be present.
Therefore I need to code this data into something that I can assign both a label for the data, and the data value. I'm guessing the best way to do this would be with an JSON object.
How can I create a key->value pair object? I would need to replace my .push() code above to instead add the value of COMPANY NAME -> Test Corp so that it can be deciphered later.
For reference, I am then stringifying this data and using an AJAX request to POST it to a PHP script where it will need to be arranged into variables e.g $company_name = 'Test Corp';
You're talking about a plain JavaScript object. JSON is a transfer format inspired by JavaScript syntax.
To make an object, just initialize a variable:
var values = {};
And add properties:
values.accountNumber = "123456789";
values.firstName = "Joe";
etc. If you know the properties up front and have values available, you can make the object in one step:
var values = {
accountNumber: "12345678",
firstName: "Joe",
// ...
};

JSON decode list of lists in Django Python

I have a list of lists (e.g. [[1,2],[3,4]]) passed from a Django view to a javascript variable and submitted with jQuery. I need to parse that variable to pull indices. The basic process is:
Add as context variable (python):
resultMsgList.append(msg)
resultMsgListJson=json.dumps(resultMsgList)
resultDict['resultMsgListJson']= resultMsgListJson
Javascript:
var resultMsgList = {{resultMsgListJson}};
var data = {'resultMsgList':resultMsgList};
$.post(URL, data, function(result){
});
Google Console gives me:
Javascript:
var resultMsgList = [["View \"S03_2005_LUZ_140814_105049_with_geom\" was successfully created!", "luz_mapfile_scen_tdm_140814_105049", "S03_2005_LUZ_140814_105049_with_geom", "C:/djangoProjects/web_output/mapfiles/ATLANTA/luz_mapfile_scen_tdm_140814_105049.map", [25, 50, 498.26708421479, 131137.057816715]]];
I copied this result to a validator, which states it is correct JSON.
The post gives me:
resultMsgList[0][]:View "S03_2005_LUZ_140814_105049_with_geom" was successfully created!
resultMsgList[0][]:luz_mapfile_scen_tdm_140814_105049
resultMsgList[0][]:S03_2005_LUZ_140814_105049_with_geom
resultMsgList[0][]:C:/djangoProjects/web_output/mapfiles/ATLANTA/luz_mapfile_scen_tdm_140814_105049.map
resultMsgList[0][4][]:25
resultMsgList[0][4][]:50
resultMsgList[0][4][]:498.26708421479
resultMsgList[0][4][]:131137.057816715
I need to get elements from this list. I currently have (python):
resultMsgListContext = request.POST.get('resultMsgListJson','')
resultMsgListContext = json.loads(resultMsgListContext)
oldMapfileName=resultMsgListContext[0][2] (+ a number of similar statements)
According to this post I then need to decode the variable in python with json.loads(), but it says there is no JSON object to be decoded. Based on the examples in the Python docs, I'm not sure why this doesn't work.
I believe the problem is that it is viewing the entire resultMsgList as a string, substantiated by the fact that there is a u' xxxxx ' in the result. That's why it is saying index out of range because you're trying to access a 2D array when it is still a string. You have to convert it to an array of strings by using json.loads.
In javascript, try passing
var data = {'resultMsgListJson':resultMsgList};
instead of
var data = {'resultMsgListJson': resultMsgListJson};
resultMsgListJson isn't a javascript variable that's defined at that point, it might be getting evaluated to undefined.
In general, in python, print the contents of resultMsgListContext before trying to do json.loads on it so you can see exactly what you're trying to parse.

Can I convert a json input to a list of objects within jquery?

I'm new to jQuery and just playing for fun. I have some code that I want to try to modify for my needs but the current js file is getting its data from google spreadsheets and then returning each item as objects. I don't use json to pass data from my server to jQuery so I'm wondering how I can convert json to objects.
The current way its doing it is(tabletop is the name of their js program that gets data from google docs):
Tabletop.init({
key: timelineConfig.key,
callback: setupTimeline,
wanted: [timelineConfig.sheetName],
postProcess: function(el){
//alert(el['photourl']);
el['timestamp'] = Date.parse(el['date']);
el['display_date'] = el['displaydate'];
el['read_more_url'] = el['readmoreurl'];
el['photo_url'] = el['photourl'];
}
});
I have added alerts all over the file and I think this is the area that gets the data and passes it on. I was thinking of trying to replace items in their object with objects from my json and see if it changes anything, but I'm unsure. Typrically I pass individual items via json,hashmaps, and lists, not sure how it works with objects or how to access objects(I simply call url's that I create for the requests, $("#user-history").load("/cooltimeline/{{ user.id }}");). But where do I start if I want to turn json data into objects?
If it helps, here's the demo of what I'm trying to do(but by having it use json data).
p.s. I'm really looking for the logic of how to complete what I'm trying to do and perhaps some ideas I'm missing so I can google them and learn.
Use use function JSON.parse(json) :) Or jQuery.parseJSON(json)
var json = '{"a":2}';
var object = JSON.parse(json);
alert(object.a);
You should see alert with message: 2
I don't realy know if I understand your comment, but maybe you want just do this:
postProcess: function(el){ //here el is JSON string
el = JSON.parse(el); // now el is an object
el.timestamp = Date.parse(el.date);
el.display_date = el.displaydate;
el.read_more_url = el.readmoreurl;
el.photo_url = el.photourl;
return el;
}
Btw. you do not need to use brackets on know property names without not standard names:
el['timestamp'] === el.timestamp
It will be easier if you paste your JSON

How to send js array via ajax?

I can only send string or numeric values,how to send an array?
You'll probably get a slew of answers all saying "JSON".
Here are some case specific examples. 'data' holds what you send.
var numArray = [17, 42, 23];
data = '[' + numArray + ']';
var strArray = ['foo', 'bar', 'baz'];
data = '["' + numArray.join('", "') + '"]';
For the general case, use a function that recursively encodes objects to JSON. If you really want me to, I'll post an example implementation, but it's a fun project so you might want to give it a try. If you're using a Javascript library, it might have a JSON encoder of it's own (such as jQuery's serializeArray).
There's are no built-in JSON serializers in javascript so you will need to use a library. A good one is json2.js.
Here's a sample:
// suppose you have an array of some objects:
var array = [{ prop1: 'value1', prop2: 10 }, { prop1: 'value2', prop2: 20 }];
// convert it to json string:
var jsonString = JSON.stringify(array);
// TODO: send the jsonString variable as a parameter in an ajax request
// On the server side you will need a JSON deserializer
// to convert values back to an array of objects
I can only send string or numeric values
Actually you can only send strings. When you include a number it is just turned into a string; it's up to the server-side script to parse that back into a number if it wants to.
how to send an array?
The native HTML-forms way of sending multiple values is using multiple inputs. You can reproduce this by including the same named parameter multiple times. To send [1,2,3]:
http://www.example.com/ajax.script?a=1&a=2&a=3
The same multiple-parameter-instance query string can be sent in an AJAX post request.
If you are using a higher-level framework to create the form-encoded string, it depends on the framework how it accepts multiple parameter instances. For example with jQuery you can post an object like {a: [1,2,3]}.
The other way is to forget the standard HTML form encoding and just pass all your values in whatever special encoding you like that allows you to retain datatypes and structure. Usually this would be JavaScript value literals (JSON):
http://www.example.com/ajax.script?a=%5B1%2C2%2C3%D
(that is, [1,2,3], URL-encoded.) You then need a JSON parser on the server to recreate native array values there.
You can actually send Arrays in a much cleaner way instead of trying to encoding JSON.
For example, this works
$.post("yourapp.php", { 'data[]': ["iphone", "galaxy"] });
See http://api.jquery.com/jQuery.post/ for more.

Categories