I have this answer from an API (written by me):
[[new Date(2017,0,28,16,00,00),[0.201766,0.201766,0.201766],[0.309878,0.309878,0.309878],[0.287467,0.287467,0.287467],[null,null,null], ...
I want my view to interpret this answer as javascript, but it doesn't. It assumes it is a string.
$.getJSON('http://localhost:XXXX/...', function (data) {
// data.jsAlignedData == [[new Date(2017,0,28,16,00,00),[0.201766,0.201766,0.201766], ...
console.log(data.jsAlignedData);
// Shows it as a string
var test = JSON.parse(data.jsAlignedData);
// Error: Unexpected token e in JSON at position 3
// (IMO it's the 'e' from 'new')
// it doesn't even reach this point:
console.log(test);
}
The final goal is to build a Dygraphs plot with a native array for increased speed (see "native array" in the documentation).
You have to serialize to date using JSON standard (see https://en.wikipedia.org/wiki/ISO_8601 for example) to be able to parse it using JSON.parse().
Edit: "JSON standard" for date type is inaccurate because you will have to interpret the date string as a JS date once parsed... (as stated in #charlietfl comment)
Related
I am passing dictionary from python to java script,
when I print this dictionary in java script it gets printed as string,
I confirmed this by checking its type. I want to convert this string into
object so that I can access the key value pairs,
when I try to parse this string I am getting error
data object looks like this
{
'AMARAJABAT': 'https://kite.zerodha.com/chart/ext/tvc/NFO-OPT/AMARAJABAT21SEP710CE/15738370',
'ASIANPAINT': 'https://kite.zerodha.com/chart/ext/tvc/NFO-OPT/ASIANPAINT21SEP3300CE/16292866',
'ASTRAL' : 'https://kite.zerodha.com/chart/ext/tvc/NFO-OPT/ASTRAL21SEP2100CE/15201026',
'AXISBANK' : 'https://kite.zerodha.com/chart/ext/tvc/NFO-OPT/AXISBANK21SEP800CE/16441858'
}
.
eventSource.addEventListener("online", function(e) {
let data = e.data
console.log(data) // this prints dictionary
console.log(typeof(data)) // this prints string
let obj = JSON.parse(data) // error at this line
console.log(obj)
}, true)
I am getting error as following:
Uncaught SyntaxError: Unexpected token ' in JSON at position 1
at JSON.parse (<anonymous>)
how can I solve this?
I guess that's what happens when you ask a Python question and use the javascript tag :-P
Instead of trying to write your own JSON encoder with something like the
yield f"id: 1\ndata: {stock_dic}\nevent: online\n\n
from your comment, you should use a proper JSON encoder. Of course there's one for Python as well, even in Python.
So something like
yield json.dumps(mydictionary)
As mentioned in comments, this issue can be solved by replacing ' by ''.
before yielding dictionary I converted it to string using
json.dumps()
This way single quotations were replaced by double quoatation.
I ultimately have to consume some data from a Javascript file that looks as follows:
Note: The base64 is illustrative only.
function GetTripsDataCompressed() { return 'QlpoOTFBWSZTWdXoWuEDCAgfgBAHf/.....=='; }
GetTripsDataCompressed() returns a base64 string that is derived as an array of objects converted to JSON using JSON.NET and the resulting string then compressed to bzip2 using SharpCompress with the resulting memory stream Base64 encoded.
This is what I have and cannot change it.
I am struggling to find a bzip2 JavaScript implementation that will take the result of:
var rawBzip2Data = atob(GetTripsDataCompressed());
and convert rawBzip2Data back into the string that is the JSON array. I cannot use something like compressjs as I need to support IE 10 and as it uses typed arrays that means IE10 support is out.
So it appears that my best option is https://github.com/antimatter15/bzip2.js however because I have not created an archive and only bzip2 a string it raises an error of Uncaught No magic number found after doing:
var c = GetTripsDataCompressed();
c = atob(c);
var arr = new Uint8Array(c);
var bitstream = bzip2.array(arr);
bzip2.simple(bitstream);
So can anyone help me here to decompress a BZip2, Base64 encoded string from JavaScript using script that is IE 10 compliant? Ultimately I don't care whether it uses https://github.com/antimatter15/bzip2.js or some other native JavaScript implementation.
It seems to me the answer is in the readme:
decompress(bitstream, size[, len]) does the main decompression of a single block. It'll return -1 if it detects that it's the final block, otherwise it returns a string with the decompressed data. If you want to cap the output to a certain number of bytes, set the len argument.
Also, keep in mind the repository doesn't have a license attached. You'll need to reach out to the author if you want to use the code. That might be tricky given that the repository is eight years old.
On the other hand, the Bzip2 algorithm itself is open-source (BSD-like license), so you can just reimplement it yourself in Javascript. It's just a few hundred lines of relatively straight-forward code.
I have built a MVC site and I am passing in my model to the view and attempting to use it in some javascript in the view using:
var records = #Html.Raw(Json.Encode(Model));
I am aiming on using these records in a custom calendar object that accepts an object array as a datasource. However, the datasource expects date variables to know where to put appointments etc. I've read that Json does not have any date format of it's own. So, all the dates that are returned from the encode are formatted like:
/Date(1462921200000)/
The object doesn't seem to accept this and nothing is shown on the view. In the posts that I've read they have stated that you can parse the date back into the correct format but this seems to be only on individual values.
My question is: is there an easy way to take the encoded object I've got and parse the dates into the correct format? Or would I have to loop through them in order to do it?
Thanks.
Warning: This answer is opinionated.
The opinionated part is: when you need something done with Json, use Json.Net.
namespace System.Web.MVC
{
public static class HtmlHelperJsonExtensions
{
public string JsonEncode(this System.Web.MVC.HtmlHelper html, object o)
{
var jsonSettings = new Newtonsoft.Json.JsonSerializerSettings()
{
// Here you can apply a LOT of formatting, as a small example regarding dates:
// 1 - formats dates as iso strings (probably what you want)
DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat,
// 2 - formats dates with Microsoft format (what you're experiencing)
//DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat,
// 3 - formats date in a custom format as for DateTime.ToString(string) overload
//DateFormatString = "yyyy-MM-dd"
Formatting = Indented
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(o, jsonSettings);
return html.Raw(json);
}
}
}
Usage:
var records = #Html.JsonEncode(Model);
Refer to the excellent Json.Net documentation here for insights.
Asp.Net MVC application return the dates in the ISO-8601 format by default.
You can convert the value in the client side with a function like this:
function ConvertDate(dateString) {
return new Date(parseInt(dateString.replace("/Date(", "").replace(")/", ""), 10));
}
Or you can use a library like momentjs (https://momentjs.com/docs/#/parsing/asp-net-json-date/):
moment("/Date(1198908717056-0700)/"); // 2007-12-28T23:11:57.056-07:00
Disclaimer: question was not identified as ASP.NET when I composed this answer. I presume the OP is asking for some feature provided by his yet to be disclosed framework. I keep the answer because I think it's valid for manual decoding in vanilla JavaScript.
The format can be parsed with a simple regular expression
var asText = "Date(1462921200000)";
var asDate = null;
var parsed = asText.match(/^Date\((\d+)\)$/);
if (parsed!==null) {
asDate = new Date(+parsed[1]);
}
console.log(asDate);
Short description:
Is there a javascript JSON-converter out there that is able to preserve Dates and does not use eval?
Example:
var obj1 = { someInt: 1, someDate: new Date(1388361600000) };
var obj2 = parseJSON(toJSON(obj1));
//obj2.someDate should now be of type Date and not String
//(like in ordinary json-parsers).
Long description:
I think most people working with JSON already had the problem of how to transmit a Date:
var obj = { someInt: 1, someDate: new Date(1388361600000) }
When converting this to JSON and back, the date suddenly became a String:
JSON.parse(JSON.stringify(obj))
== { someInt: 1, someDate: "2013-12-30T00:00:00.000Z" }
This is a huge disadvantage since you cannot easily submit a Date using JSON. There is always some post-processing necessary (and you need to know where to look for the dates).
Then Microsoft found a loophole in the specification of JSON and - by convention - encodes a date as follows:
{"someInt":1,"someDate":"\/Date(1388361600000)\/"}
The brilliance in this is that there is a now a definitive way to tell a String from a Date inside a valid JSON-string: An encoded String will never contain the substring #"/" (a backslash followed by a slash, not to be confused with an escaped slash). Thus a parser that knows this convention can now safely create the Date-object.
If a parser does not know this convention, the date will just be parsed to the harmless and readable String "/Date(1388361600000)/".
The huge drawback is that there seems to be no parser that can read this without using eval. Microsoft proposes the following way to read this:
var obj = eval("(" + s.replace(/\"\\\/Date\((\d+)\)\\\/\"/g, function (match, time) { return "new Date(" + time + ")"; }) + ")");
This works like a charm: You never have to care about Dates in JSON anymore. But it uses the very unsafe eval-method.
Do you know any ready-to-use-parser that achieves the same result without using eval?
EDIT
There was some confusion in the comments about the advantages of the tweaked encoding.
I set up a jsFiddle that should make the intentions clear: http://jsfiddle.net/AJheH/
I disagree with adeno's comment that JSON is a notation for strings and cannot represent objects. Json is a notation for compound data types which must be in the form of a serialized objects, albeit that the primitive types can only be integer, float, string or bool. (update: if you've ever had deal with spaghetti coded XML, then you'll appreciate that maybe this is a good thing too!)
Presumably hungarian notation has lost favour with Microsoft if they now think that creating a non-standard notation incorporating the data type to describe a type is better idea.
Of itself 'eval' is not evil - it makes solving some problems a lot easier - but it's very difficult to implement good security while using it. Indeed it's disabled by default with a Content Security Policy.
IMHO it boils down to storing the date as 1388361600000 or "2013-12-30T00:00:00.000Z". IMHO the latter has significantly more semantic value - taken out of context it is clearly a date+time while the latter could be just about anything. Both can be parsed by the ECMAscript Date object without resorting to using eval. Yes this does require code to process the data - but what can you do with an sort of data without parsing it? he only time I can see this as being an advanage is with a schemaless database - but in fairness this is a BIG problem.
The issue is the following line of code, here is an example function and take a look at parseWithDate function, add the script to the page and change the following line to this it will work.
http://www.asp.net/ajaxlibrary/jquery_webforms_serialize_dates_to_json.ashx
var parsed1 = JSON.parse(s1); // changed to below
var parsed1 = JSON.parseWithDate(s1);
Updated jsFiddle that works http://jsfiddle.net/GLb67/1/
I have a site and I used AJAX. And I got some problems.
Server return JSON string something like this {a:"x48\x65\x6C\x6C\x6F"}.
Then in xx.responseText, we have this string '{a:"\x48\x65\x6C\x6C\x6F"}'.
But if I create JavaScript string "\x48\x65\x6C\x6C\x6F" then I have "Hello" and not HEX!
Is it possible get in xx.responseText "real" text from HEX (automatically, without .replace())?
If the output is at all regular (predictable), .replace() is probably the simplest.
var escapeSequences = xx.responseText.replace(/^\{a:/, '').replace(/\}$/, '');
console.log(escapeSequences === "\"\\x48\\x65\\x6C\\x6C\\x6F\""); // true
Or, if a string literal that's equivalent in value but may not otherwise be the same is sufficient, you could parse (see below) and then stringify() an individual property.
console.log(JSON.stringify(data.a) === "\"Hello\""); // true
Otherwise, you'll likely need to run responseText through a lexer to tokenize it and retrieve the literal from that. JavaScript doesn't include an option for this separate from parsing/evaluating, so you'll need to find a library for this.
"Lexer written in JavaScript?" may be a good place to start for that.
To parse it:
Since it appears to be a string of code, you'll likely have to use eval().
var data = eval('(' + xx.responseText + ')');
console.log(data.a); // Hello
Note: The parenthesis make sure {...} is evaluated as an Object literal rather than as a block.
Also, I'd suggest looking into alternatives to code for communicating data like this.
A common option is JSON, which takes its syntax from JavaScript, but uses a rather strict subset. It doesn't allow functions or other potentially problematic code to be included.
var data = JSON.parse(xx.responseText);
console.log(data.a); // Hello
Visiting JSON.org, you should be able to find a reference or library for the choice of server-side language to output JSON.
{ "a": "Hello" }
Why not just let the JSON parser do its job and handle the \x escape sequences, and then just convert the string back to hex again afterwards, e.g.
function charToHex(c) {
var hex = c.charCodeAt(0).toString(16);
return (hex.length === 2) ? hex : '0' + hex;
}
"Hello".replace(/./g, charToHex); // gives "48656c6c6f"