JSON.parse() works from console but not from function/code - javascript

Why parsing string into JSON (previously created with JSON.stringify()) works from console but from function it gives enigmatic error?
console.log(output); // in console i copy it into JSON.parse() and it works
output = JSON.parse(output); // Uncaught SyntaxError: Unexpected token index:1
My JSON:
{"type":"a","items":[{"id":"767758","id1":"1384882","id2":"1413749","c":"rgba(0, 100, 0, 5)","ls":"dashed","type":"l","d":{"t":"r","type":"1","hist":true},"w":5,"off":0},{"id":"6493942","id1":"1384882","id2":"5467332","c":"rgba(105, 105, 105, 5)","ls":"1","type":"l","d":{"t":"r","type":"h","hist":false},"w":5,"off":0},{"id":"1384882","id":"6c409d02-d937-11e4-a891-53b449010d08","d":{"t":"p","age":41,"xxx":5},"type":"n","t":"123","u":"p.png","g":[{"c":"rgb(255, 255, 255)","p":"ne","t":"5","fc":"rgb(0, 0, 0 )","w":false}],"x":-20.876105573962775,"y":41.26542299248838},{"id":"1413749","id":"e7e70a00-d3e4-11e4-b3ef-53b449010d08","d":{"t":"c","active":true,"r":47},"type":"n","t":"zxc","u":"p.png","g":[{"c":"#ccff99","p":"ne","t":"42","fc":"rgb(0, 0, 0)","w":5},{"c":"rgb(0, 0, 255)","p":"nw","fc":"rgb(0, 0, 0)"}],"x":149.06285284387724,"y":5.308329729351229},{"id":"5467332","id":"8f0f5c30-d3d9-11e4-b3ef-53b449010d08","d":{"t":"c","active":true,"r":47},"type":"n","t":"asd","u":"p.png","g":[{"c":"#ccff99","p":"ne","t":"","fc":"rgb(0, 0, 0)","w":false},{"p":"nw","fc":"rgb(0, 0, 0)"}],"x":-164.24347467678655,"y":-32.64876353378594}],"combos":{"iop":[],"dfg":[]},"jk":{"width":966,"height":890,"zoom":5,"offsetX":905,"offsetY":744}}
My code, there's something missing as others gave working JSfiddles:
var memory = '';
$buttonSave.click(function (event) {
if (helpers.isNUE(chart)) { return; }
var data = chart.serialize();
data = JSON.stringify(data).split(''); // string to array
data.forEach(function (datum) { // foreach character
memory += datum.charCodeAt(0).toString(2) + '2'; // get binary charcode, add padding "2"
});
console.info('memory saved: ' + memory);
event.preventDefault();
return false;
});
$buttonLoad.click(function (event) {
var data = memory.split('2'), // get binary code for each character
output = '',
serializedChart = {};
data.forEach(function (datum) {
output += String.fromCharCode(parseInt(datum, 2)); // read binary charcode and get character from it
});
console.warn('load done:');
try {
serializedChart = JSON.parse(output);
} catch (e) {
console.warn(e);
}
});

You are missing a final } from your json string. use this:
{
"type": "a",
"items": [
{
"id": "767758",
"id1": "1384882",
"id2": "1413749",
"c": "rgba(0, 100, 0, 5)",
"ls": "dashed",
"type": "l",
"d": {
"t": "r",
"type": "1",
"hist": true
},
"w": 5,
"off": 0
},
{
"id": "6493942",
"id1": "1384882",
"id2": "5467332",
"c": "rgba(105, 105, 105, 5)",
"ls": "1",
"type": "l",
"d": {
"t": "r",
"type": "h",
"hist": false
},
"w": 5,
"off": 0
},
{
"id": "6c409d02-d937-11e4-a891-53b449010d08",
"d": {
"t": "p",
"age": 41,
"xxx": 5
},
"type": "n",
"t": "123",
"u": "p.png",
"g": [
{
"c": "rgb(255, 255, 255)",
"p": "ne",
"t": "5",
"fc": "rgb(0, 0, 0 )",
"w": false
}
],
"x": -20.876105573962775,
"y": 41.26542299248838
},
{
"id": "e7e70a00-d3e4-11e4-b3ef-53b449010d08",
"d": {
"t": "c",
"active": true,
"r": 47
},
"type": "n",
"t": "zxc",
"u": "p.png",
"g": [
{
"c": "#ccff99",
"p": "ne",
"t": "42",
"fc": "rgb(0, 0, 0)",
"w": 5
},
{
"c": "rgb(0, 0, 255)",
"p": "nw",
"fc": "rgb(0, 0, 0)"
}
],
"x": 149.06285284387724,
"y": 5.308329729351229
},
{
"id": "8f0f5c30-d3d9-11e4-b3ef-53b449010d08",
"d": {
"t": "c",
"active": true,
"r": 47
},
"type": "n",
"t": "asd",
"u": "p.png",
"g": [
{
"c": "#ccff99",
"p": "ne",
"t": "",
"fc": "rgb(0, 0, 0)",
"w": false
},
{
"p": "nw",
"fc": "rgb(0, 0, 0)"
}
],
"x": -164.24347467678655,
"y": -32.64876353378594
}
],
"combos": {
"iop": [],
"dfg": []
},
"jk": {
"width": 966,
"height": 890,
"zoom": 5,
"offsetX": 905,
"offsetY": 744
}
}

Is output already parsed? If so, it looks like you're trying to parse output twice, if the output is already a JSON value, you do not need to parse it again.

You're missing an } at the end of your JSON. If you add that it should work.
{"type":"a","items":[{"id":"767758","id1":"1384882","id2":"1413749","c":"rgba(0, 100, 0, 5)","ls":"dashed","type":"l","d":{"t":"r","type":"1","hist":true},"w":5,"off":0},{"id":"6493942","id1":"1384882","id2":"5467332","c":"rgba(105, 105, 105, 5)","ls":"1","type":"l","d":{"t":"r","type":"h","hist":false},"w":5,"off":0},{"id":"1384882","id":"6c409d02-d937-11e4-a891-53b449010d08","d":{"t":"p","age":41,"xxx":5},"type":"n","t":"123","u":"p.png","g":[{"c":"rgb(255, 255, 255)","p":"ne","t":"5","fc":"rgb(0, 0, 0 )","w":false}],"x":-20.876105573962775,"y":41.26542299248838},{"id":"1413749","id":"e7e70a00-d3e4-11e4-b3ef-53b449010d08","d":{"t":"c","active":true,"r":47},"type":"n","t":"zxc","u":"p.png","g":[{"c":"#ccff99","p":"ne","t":"42","fc":"rgb(0, 0, 0)","w":5},{"c":"rgb(0, 0, 255)","p":"nw","fc":"rgb(0, 0, 0)"}],"x":149.06285284387724,"y":5.308329729351229},{"id":"5467332","id":"8f0f5c30-d3d9-11e4-b3ef-53b449010d08","d":{"t":"c","active":true,"r":47},"type":"n","t":"asd","u":"p.png","g":[{"c":"#ccff99","p":"ne","t":"","fc":"rgb(0, 0, 0)","w":false},{"p":"nw","fc":"rgb(0, 0, 0)"}],"x":-164.24347467678655,"y":-32.64876353378594}],"combos":{"iop":[],"dfg":[]},"jk":{"width":966,"height":890,"zoom":5,"offsetX":905,"offsetY":744}}

What is typeof output? For parse() to work, it must be string but the dump in your question looks like it would return object. object means that the JSON has already been parsed and it's a JavaScript object.
So this would work:
var output = '{"type":"a","items":[{...}]}';
output = JSON.parse(output);
while this won't:
var output = {
"type":"a",
"items":[{...}]
};
output = JSON.parse(output);

Related

I'd like to filter out objects which do not have an ext key on them

How can I remove objects which do not have an ext key? I want to take pictures, but there is a problem because some objects do not have a picture. I'm confused about filtering. Can it be done with reduce or filter?
{
"posts": [
{
"filename": "1647706792183",
"ext": ".png",
"w": 300,
"h": 450,
"tn_w": 166,
"tn_h": 250,
"tim": 1664328637690788,
"time": 1664328637,
"md5": "Omk9VtmPOD1U38U1OOAP/w==",
"fsize": 200271,
"resto": 0,
"country": "DK",
"bumplimit": 0,
"imagelimit": 0,
"semantic_url": "f1-relentless-formula-one-general-all-smiles",
"replies": 378,
"images": 155,
"unique_ips": 102,
"tail_size": 50
},
{
"now": "09/27/22(Tue)21:31:17",
"name": "Anonymous",
"resto": 123946553,
}
]
}
You can use .filter to run a function that returns true/false for each item of your data.
const data = { posts: [ .... ] };
const postsWithExt = data.posts.filter(post => post.ext !== undefined);
If you want to filter falsy values for .ext then use
posts.filter(post => !post.ext)
You can just filter your posts array where the ext property exists.
e.g.
const data = {
"posts": [{
"filename": "1647706792183",
"ext": ".png",
"w": 300,
"h": 450,
"tn_w": 166,
"tn_h": 250,
"tim": 1664328637690788,
"time": 1664328637,
"md5": "Omk9VtmPOD1U38U1OOAP/w==",
"fsize": 200271,
"resto": 0,
"country": "DK",
"bumplimit": 0,
"imagelimit": 0,
"semantic_url": "f1-relentless-formula-one-general-all-smiles",
"replies": 378,
"images": 155,
"unique_ips": 102,
"tail_size": 50
},
{
"now": "09/27/22(Tue)21:31:17",
"name": "Anonymous",
"resto": 123946553,
}
]
};
const result = data.posts.filter(x => x.ext);
console.log(result);

Converting one data structure to another

Hi I need to parse some structure to to show some data in line chart. I have this data structure , and I need to convert it for array example_output:
data = {
"el1": [{
"date": "2017.01",
"data1": {
"series_1": {
"a": 10,
"b": 20,
"c": 50,
"d": 15,
"e": 8
},
"Series_2": {
"yes": 5,
"no": 3
},
"Series_3": {
"s": 2,
"n": 9
}
},
"text": [{
"t": "header",
"c": "text"
}, {
"t": "header2",
"c": "text2"
}]
}, {
"date": "2017.02",
"data1": {
"series_1": {
"a": 56,
"b": 23,
"c": 45,
"d": 69,
"e": 14
},
"Series_2": {
"yes": 2,
"no": 1
},
"Series_3": {
"s": 6,
"n": 4
}
},
"text": [{
"t": "header",
"c": "text"
}, {
"t": "header2",
"c": "text2"
}]
}, {
"date": "2017.03",
"data1": {
"series_1": {
"a": 15,
"b": 12,
"c": 10,
"d": 54,
"e": 4
},
"Series_2": {
"yes": 20,
"no": 16
},
"Series_3": {
"s": 9,
"n": 7
}
},
"text": [{
"t": "header",
"c": "text"
}, {
"t": "header2",
"c": "text2"
}]
}
]
};
and I need OUTPUT like this for chartist.js
var example_output = [{
labels: ['2017.01', '2017.02', '2017.03'],
series: {
[10, 56, 15],
[20, 23, 12],
[50, 45, 10],
[15, 69, 54],
[8, 14, 4]
},
labels: ['2017.01', '2017.02', '2017.03'],
series: {
[5, 2, 20],
[3, 1, 16]
},
labels: ['2017.01', '2017.02', '2017.03'],
series: {
[2, 6, 9],
[9, 4, 7]
},}] ;
Please compare digits from the original and the example_output to better understand how this should look like. I use code for parse this but someting goes wrong:
function parseData(data) {
var _newData = {};
var allSeries = [];
data.elements.forEach(function(el){
_newData[el.date] = el.info
if(allSeries.length==0)
allSeries = Object.keys(el.info);
});
return allSeries.map(function(el) {
var obj = {
labels: [],
series: []
};
obj.labels = Object.keys(_newData);
Object.keys(_newData).forEach(function(_el) {
obj.series.push(Object.values(_newData[_el][el]));
});
var _newSeries = [];
obj.series[0].forEach(function(el, i){
_newSeries.push([el, obj.series[1][i]]);
});
obj.series = _newSeries;
return obj;
});
}
You can use array#forEach and array#reduce. Use first loop to iterate through el1 and then use reduce for the series key and accumulate the result in the output_example.
NOTE: The series in your output is incorrect. It should be an array instead of object.
const data = {"el1": [{"date": "2017.01","data1": {"series_1": {"a": 10,"b": 20,"c": 50,"d": 15,"e": 8},"Series_2": {"yes": 5,"no": 3},"Series_3": {"s": 2,"n": 9}},"text": [{"t": "header","c": "text"}, {"t": "header2","c": "text2"}]}, {"date": "2017.02","data1": {"series_1": {"a": 56,"b": 23,"c": 45,"d": 69,"e": 14},"Series_2": {"yes": 2,"no": 1},"Series_3": { "s": 6,"n": 4 }},"text": [{"t": "header","c": "text"}, {"t": "header2","c": "text2"}]}, {"date": "2017.03","data1": {"series_1": {"a": 15,"b": 12,"c": 10,"d": 54,"e": 4},"Series_2": {"yes": 20, "no": 16},"Series_3": {"s": 9, "n": 7}},"text": [{"t": "header","c": "text"}, {"t": "header2","c": "text2" }]}]};
transpose = (arr) => arr.reduce((r,v,i) => {
(r[i] = r[i] || []).push(v);
return r;
},[]);
let example_output = [];
data.el1.forEach((o) => {
Object.keys(o.data1).reduce((r, k, i) => {
r[i] = r[i] || {};
if('labels' in r[i])
r[i]['labels'].push(o.date);
else
r[i]['labels'] = [o.date];
if('series' in r[i])
Object.values(o.data1[k]).forEach((v,j) => r[i]['series'][j].push(v));
else
r[i]['series'] = transpose(Object.values(o.data1[k]));
return r;
},example_output);
},[]);
console.log(example_output);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Normalise JSON object key names

I am wanting to write a function to turn a JSON object's keys into more appropriate names. As you can see by the JSON object below, the keys are 1 letter and are not very readable or useful for anyone. Therefore I would like to loop through the object (or something similar) and rename all the keys, and then return this JSON.
{
"e": "56049",
"pp": "371861",
"c": "GAME",
"x": 2,
"st": "2017-04-27T15:01:29Z",
"o": 0,
"r": true,
"u": "2017-04-27T15:01:29Z",
"t": "p",
"i": "371871",
"z": 1493305289586
}
You can reduce object keys to new object, e.g.:
const obj = {
"e": "56049",
"pp": "371861",
"c": "GAME",
"x": 2,
"st": "2017-04-27T15:01:29Z",
"o": 0,
"r": true,
"u": "2017-04-27T15:01:29Z",
"t": "p",
"i": "371871",
"z": 1493305289586
}
// [key] -> [normalized name] mapping
const names = {
"e": "e-name",
"pp": "pp-name",
"c": "c-name",
"x": "x-name",
"st": "st-name",
"o": "o-name",
"r": "r-name",
"u": "u-name",
"t": "t-name",
"i": "i-name",
"z": "z-name"
}
const renamedProps = Object.keys(obj).reduce((renamed, key) => {
renamed[names[key]] = obj[key];
return renamed;
}, {});
var obj = {
"e": "56049",
"pp": "371861",
"c": "GAME",
"x": 2
},
names = ["e_new-name", "pp_new-name", "c_new-name", "x_new-name"],
updated = {},
keys = Object.keys(obj);
for (i = 0; i < keys.length; i++) {
updated[names[i]] = obj[keys[i]];
}
console.log(JSON.stringify(updated));
// will print
// {"e_new-name":"56049","pp_new-name":"371861","c_new-name":"GAME","x_new-name":2}
jsfiddle

Generating dictionaries and lists in JavaScript after a JSON

I'm receiving a JSON in this format:
{
"0": {
"a": 0.0,
"b": 1.0,
"G": 6.0,
"w": 0.0,
"F": -1.0
},
"1": {
"a": 0.0,
"b": 0.1429004669189453,
"G": 0.000301361083984375,
"w": 0.1429004669189453,
"F": -1.0
},
"2": {
"a": 0.0,
"b": 0.1429004669189453,
"G": 0.000301361083984375,
"w": 0.1429004669189453,
"F": -1.0
},
"3": {
"a": 0.0,
"b": 0.1429004669189453,
"G": 0.000301361083984375,
"w": 0.1429004669189453,
"F": -1.0
....
Let's say I call that a json variable. I'm trying to turn it into something like:
[
{"key": "series1",
values: [
[`json`["1"]["a"],`json`["1"]["F"]],[`json`["1"]["b"],`json`["1"]["G"]]
]
},
{"key": "series2",
values: [
[`json`["2"]["a"],`json`["2"]["F"]],[`json`["2"]["b"],`json`["2"]["G"]]
]
},
{"key": "series3",
values: [
[`json`["3"]["a"],`json`["3"]["F"]],[`json`["3"]["b"],`json`["3"]["G"]]
]
},
....
]
I tried this JavaScript for accomplishing it but got lost :S
var data = function myData(json) {
series = {}
for (iteracion in json) {
series.push({
key: iteracion, values: [[x: iteracion['a'], y: iteracion['F']],[x: iteracion['b'], y: iteracion['G']]]
})
}
return series
A solution to your problem is:
var result = [];
for (var series in json) {
result.push({
key : 'series' + series,
values : [
json[series].a,
json[series].F,
json[series].b,
json[series].G,
]
});
}
If you don't really need an array of objects that contain a key and a value, i organized your information slightly better:
var result = {};
for (var series in json) {
result['series' + series] = [
json[series].a,
json[series].F,
json[series].b,
json[series].G,
];
}
This results in something like this:
{
series0 : [ 0, -1, 1, 6 ],
series1 : [ 0, -1, 0.14, 0.0003],
...
}

How to get image url

If I parse a Tweet from the Twitter API using:
tweet.entities.media
I get the below json. But how would I access media_url property? Its nested in a really difficult place inside the json object.
tweet.entities.media[0].media_url
returns an error.
{
"image": [
{
"id": 511403875438301200,
"id_str": "511403875438301185",
"indices": [
44,
66
],
"media_url": "http://some_url.jpg",
"media_url_https" : "https: //some_url.jpg",
"url": "http://whatever.com",
"display_url": "pic.twitter.com/BNIPh3ZlRD",
"expanded_url": "https://twitter.com/some_url/1",
"type": "photo",
"sizes": {
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"small": {
"w": 680,
"h": 482,
"resize": "fit"
},
"large": {
"w": 2048,
"h": 1453,
"resize": "fit"
},
"medium": {
"w": 1200,
"h": 851,
"resize": "fit"
}
}
}
]
}
how would I access media_url?
It appears to me that you are just missing image[0]:
tweet.entities.media.image[0].media_url
$(document).ready(function() {
var tweet = jQuery.parseJSON( '{"entities":{"media":{"image":[{"id":511403875438301200,"id_str":"511403875438301185","indices":[44,66],"media_url":"http://pbs.twimg.com/media/BxjfHXxCEAETmig.jpg","media_url_https":"https: //pbs.twimg.com/media/BxjfHXxCEAETmig.jpg","url":"http://whatever.com","display_url":"pic.twitter.com/BNIPh3ZlRD","expanded_url":"https://twitter.com/AWish4Me/status/511403876642463744/photo/1","type":"photo","sizes":{"thumb":{"w":150,"h":150,"resize":"crop"},"small":{"w":680,"h":482,"resize":"fit"},"large":{"w":2048,"h":1453,"resize":"fit"},"medium":{"w":1200,"h":851,"resize":"fit"}}}]}}}');
document.body.innerHTML = tweet.entities.media.image[0].media_url;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I think I got it.
It was breaking because some of the Tweets didn't have images..
I had to check for empty properties...
return {"image_url":(tweet.entities.media!==undefined)?((tweet.entities.media[0]!=="")?(tweet.entities.media[0].media_url):('')): ('') };

Categories