Getting an error with this JSON response - javascript

I keep getting the error: Uncaught SyntaxError: Unexpected token '
this is the full JSON response:
'app': {type: 'app', desc: 'Application'}, 'iso': {type: 'iso', desc: 'ISO Disk Image'}, 'fla': {type: 'fla', desc: 'Adobe Flash Document'}, 'dll': {type: 'dll', desc: 'Dynamic Link Library'}
I've tried putting brackets around the full response too, but that doesn't fix it. Am I doing JSON wrong? I've tried removing the parentheses but then it complains about characters. I'm trying to turn this response into a JavaScript Object, but it just doesn't want to do it!

A couple of problems there:
In JSON, keys must be in double quotes (so must strings). Single quotes aren't allowed, and quotes are required.
In JSON, the top level must always be an object or an array. You've quoted a series of property initializers, which must be inside an object.
Here's the valid version of that:
{
"app": {"type": "app", "desc": "Application"},
"iso": {"type": "iso", "desc": "ISO Disk Image"},
"fla": {"type": "fla", "desc": "Adobe Flash Document"},
"dll": {"type": "dll", "desc": "Dynamic Link Library"}
}
Changes:
Change all single quotes to double quotes.
Put double quotes around the keys (type, desc) that didn't have them.
Put the whole thing in {} so the top level is an object.

Here is your valid JSON String
{
"app": {
"type": "app",
"desc": "Application"
},
"iso": {
"type": "iso",
"desc": "ISODiskImage"
},
"fla": {
"type": "fla",
"desc": "AdobeFlashDocument"
},
"dll": {
"type": "dll",
"desc": "DynamicLinkLibrary"
}
}
You can always check for validity on http://jsonlint.com/
If you want to look for some valid JSON formats look here

I've just add double quotes everywhere, put {} around, and it works :
var objet = '{"app": {"type": "app", "desc": "Application"},"iso": {"type": "iso", "desc": "ISO Disk Image"},"fla": {"type":"fla", "desc": "Adobe Flash Document"},"dll": {"type": "dll", "desc": "Dynamic Link Library"}}';
console.log($.parseJSON(objet));
You can retrieve my test here

See json.org for the full JSON standard.
You'll see that there are two problems here:
JSON data is represented as an object ( {} ) or an array ( [] ). Therefore you need to wrap everything within one or the other, depending on what is appropriate for your data (likely object, from the looks of your data).
You also need to use double-quotation marks on your strings. From json.org:
A string is a sequence of zero or more Unicode characters, wrapped in
double quotes, using backslash escapes
Finally, you can use JSON Lint to catch these sorts of problems quickly and easily.
Here's your data in valid JSON:
{
"app": {
"type": "app",
"desc": "Application"
},
"iso": {
"type": "iso",
"desc": "ISODiskImage"
},
"fla": {
"type": "fla",
"desc": "AdobeFlashDocument"
},
"dll": {
"type": "dll",
"desc": "DynamicLinkLibrary"
}
}

Related

jquery/ajax - how to iterate through a json message with duplicate keys?

I receive with my ajax post request a message with values to display. This json response message looks like this:
{
"line": {
"name": "Google item",
"images": {
"element": {
"order": "1",
"link": "https://google.com/1.jpg",
"name": "1.jpg"
},
"element": {
"order": "2",
"link": "https://google.com/2.jpg",
"name": "2.jpg"
},
"element": {
"order": "3",
"link": "https://google.com/3.jpg",
"name": "3.jpg"
},
"element": {
"order": "4",
"link": "https://google.com/4.jpg",
"name": "4.jpg"
},
"element": {
"order": "5",
"link": "https://google.com/5.jpg",
"name": "5.jpg"
}
},
"features": {
"element": {
"name": "1",
"order": "1"
},
"element": {
"name": "2",
"order": "2"
},
"element": {
"name": "3",
"order": "3"
},
"element": {
"name": "4",
"order": "4"
}
},
"purchasing_price": "10",
"selling_price": "20",
"ftp_path": "google/item",
"description": ""
}
}
I'm in development and have not so much experience with json in jquery/ajax.
I tried this:
function parseContent(content){
$("#name").val(content.line.name);
$("#ftp_path").val(content.line.ftp_path);
$("#html_description").val(content.line.description);
$("#feature").remove();
$.each(content.line.features, function(k, v){
$("#features").append('<input type="text" class="form-control mt-3" id="feature" value="' + v.name + '" required>');
alert(v.name );
});
}
My problem is, the variable content contains just the last image und feature element. But in chrome/network I could see, the complete message has been received.
So I found out there is a parsing issue: Parsed JSON contains only the last element.
But how can I fix this in my case, to iterate through all elements?
The JSON specification says:
The names within an object SHOULD be unique.
The names in those objects are not.
SHOULD means:
that there
may exist valid reasons in particular circumstances to ignore a
particular item, but the full implications must be understood and
carefully weighed before choosing a different course.
The implications here are that every JSON parser (that I'm aware of at least) will ignore all but one of the values with duplicate names in an object.
If you really need to deal with that data then you are going to have to either track down a parser which can handle it (I'm not aware of any) or write a custom JSON parser which can (you'll also need to decide what data structure you want to generate from it because JS can't have duplicate property names in objects either). There are a number of JSON parsers on npm you might want to examine the source code of as a starting point.
A better solution would be to change whatever is generating the source data to produce a sensible format that doesn't violate a SHOULD requirement. Replacing the duplicate property names with an array for example.

How to sent windows key for google cloud platform as an JSON?

I need to attach the encoded key to the modulus in for windows set metadata rest call to get a user validated for login.
So the format which google expects is:
{
"fingerprint": string,
"items": [
{
"key": string,
"value": string
}
],
"kind": string
}
So when you are sending data to google they want in this format.
{
"fingerprint": "sfasdfasdfFSN7AuU=",
"items": [
{
"key": "windows-keys",
"value": "{\"userName\": \"user\",
\"modulus\": \"somekey\",
\"exponent\": \"AQAB\",
\"email\": \"samleemail\",
\"expireOn\": \"2019-04-14T01:37:19Z\"
}"
}
]
}
It will also accept if I send the same JSON in this below format but will not perform any action in there:
{
"fingerprint": "asfasd",
"items": [
{
"key": "windows-keys",
"value":
{
"userName": "user",
"modulus": "IEFBQUFCM056YUMxeWM",
"exponent": "AQAB",
"email": "somemailt",
"expiresOn": "2019\"04-14T01:37:19Z"
}
}
]
}
Does any one knows a solution for this or faced this issue?
Google Doc link
In the format definition you're providing, it mentions that the value property of every item in the items array should be a string, and if you look closely, the "correct" example you provide sets value as a string`
{
"key": "windows-keys",
"value": "{\"userName\": \"user\",
\"modulus\": \"somekey\",
\"exponent\": \"AQAB\",
\"email\": \"samleemail\",
\"expireOn\": \"2019-04-14T01:37:19Z\"
}"
}
However, in your second example, you're setting value as an object, so it's not in the expected format, the correct version should look something like this:
{
"fingerprint": "asfasd",
"items": [
{
"key": "windows-keys",
"value": "{\"userName\": \"user\",
\"modulus\": \"IEFBQUFCM056YUMxeWM\",
\"exponent\": \"AQAB\",
\"email\": \"somemailt\",
\"expiresOn\": \"2019-04-14T01:37:19Z\"
}"
}
]
}
That should make it at least accept your request, you might need to fill the email with a correct one and check out whether if it's "expireOn" or "expiresOn" as your examples use both

Which json structure is better for my requirements?

I want to store links and text. The links can be of image, video or gifs. And i want to store them in order the user specifies.
Ex: img1, some text, video, img2 - This should be saved as json.
So far I have come up with 2 options:
First:
{
"content": {
"0": ["image", "image-link-here"],
"1": ["text", "this is some text here"],
"2": ["image", "2nd-image-link"],
"3": ["video", "video-link"]
}
}
Second: In this case, i can know if its image, video, gif or text by extension
{
"content": ["https://somelink.com/pic.jpg", "this is a text", "https://somelink.com/pic2.png", "https://somelink.com/vid.mp4"]
}
I need to store these in DynamoDB. So which one would be good and correct keeping in mind that I expect DB to grow?
If both these approaches are bad, please suggest the good way to do it.
You should try to make arrays where each element has the same type/structure, as it will enable better searches.
The second solution is not specific enough. As a text could end with ".jpg", you'll need a more elaborate test to determine whether it is just text or not. The text might even look a lot like a URL...
The first is better, but it is not really helpful to have numerical keys. Instead you should combine per type, and use that type as the key name, and put the actual value(s) in an array value, like this:
{
"content": {
"images": ["image-link-here", "2nd-image-link"],
"texts": ["this is some text here"],
"videos": ["video-link"]
}
}
This structure should allow for most practical searches.
As you indicated in comments that you need to know the order of each item, then I would suggest to define content as an array, where the occurrence of elements in that array represent the order of them:
{
"content": [
{ "image": "image-link-here" },
{ "text": "this is some text here" },
{ "image": "2nd-image-link" },
{ "video": "video-link" }
]
}
Or, to make each of the objects have the same properties:
{
"content": [
{ "type": "image", "value": "image-link-here" },
{ "type": "text", "value": "this is some text here" },
{ "type": "image", "value": "2nd-image-link" },
{ "type": "video", "value": "video-link" }
]
}
The choice depends on which kind of queries you intend to do.

Strongloop Loopback: Filter by id of related Model

I have a Strongloop Loopback Node.js project with some models and relations.
The problem at hand
My problem relates how to query only those Media instances that have a relation to a certain Tag id, using the Angular SDK - while not querying Tags.media (which return Tag instances), but instead making a query somehow that returns plain Media instances.
Please read below for specific information..
Spec
Basically, I have a Model Media which has many 'tags' (model Tag). Think of a image file (Media) having various EXIF tags (Tag). Here is the relation spec (this all works as expected):
Media (media.json):
{
"name": "media",
"base": "PersistedModel",
"properties": {
"id": {
"type": "string",
"id": true
}
},
"relations": {
"tags": {
"type": "hasAndBelongsToMany",
"model": "tag"
}
}
Tag (tag.json):
{
"name": "tag",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"name": {
"type": "string",
"required": true
}
},
"relations": {
"medias": {
"type": "hasAndBelongsToMany",
"model": "media"
}
},
"acls": [],
"methods": []
}
Solutions
Now, I know I could do a query like this (using Angular SDK in my example, but the syntax is the same):
injector.get('Tag').find({
'filter': {
'include': 'medias',
'where': {'id': <mytagid>}
}
});
My problem with this approach is, that I receive 1 (one) Tag instance with attached Media instances. This disrupts why whole workflow as I deal only with Media instances.. i just want to filter by Tag id, not bother about Tag at all.
Bottom line
If I see the API explorer (/explorer/), the return value of GET /api/tags/<myTagID>/medias is exactly what I need - an array of Media objects - but how to query them exactly like this using the Angular SDK (lb_services)?
I had a similar problem. One recommendation is to open the lb-services.js and try to find: /tags/:id/medias or something similar. Then you will find a comment like this: // INTERNAL. Use Tags.medias() instead. Or something similar. So that is the method that you should call. Do not call the "prototype$__get....." methods.
Then just call what it says there I suppose: Tag.medias({id:})
Other suggestions:
As you said in your description Media has many Tags. So why not use just
{
"name": "media",
"base": "PersistedModel",
"properties": {
"id": {
"type": "string",
"id": true
}
},
"relations": {
"tags": {
"type": "hasMany", <---------- hasMany
"model": "tag",
"foreignKey": "tagId" <---FK name
}
}
and
for the tags just belongsTo as type.
{
"name": "tag",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"name": {
"type": "string",
"required": true
}
},
"relations": {
"medias": {
"type": "belongsTo",
"model": "media",
"foreignKey": "mediaId" <---FK name
}
},
"acls": [],
"methods": []
}
But really I don't think this is the problem because you said when you request GET /api/tags/<myTagID>/medias it returns what you want.
Then, in AngularJS you can use:
Media.tags({id:<mediaId>})
for media/:id/tags
and for the other side try:
Tag.medias({id:<tagId>})
Tag.find({
filter:{
where:{mediaId: <mediaId>} <----mediaId comes from FK name
}
})
In this case both are persistent models there is no problems, I had permission problems when doing a similar thing with data that extends User type. But that is another story...
Hope this is helpful, I changed some stuff from a similar app that I am doing and hope not making so many errors when adapting to your code...

How to access the data from return JSON from webservice in javascript or jquery

Hi i have a return json data which returns the webservice
The structure of webservice is like that:
jsonp1332655154667({"products": [{"uid": "37",
"samsid": "hjk",
"name": "Science%20Essentials%2010%20AC%20edn",
"shortname": "scienceessentials10",
"description": "Science%20Essentials%2010%20ACE%20is%20the%20fourth%20in%20a%20series%20of%20four%20books%20designed%20for%20the%20National%20Curriculum.%20",
"generated": "3/25/2012%205:59:19%20AM",
"Description": "Science%20Essentials%2010%20ACE%20is%20the%20fourth%20in%20a%20series%20of%20four%20books%20designed%20for%20the%20National%20Curriculum.%20",
"PublishingCompany": "Macmillan%20Australia",
"Service": "OneStopScience",
"Service": "OneStopDigital",
"Icon": "http://curriculumplatform.s3.amazonaws.com/prod/icons/brain48.png",
"Country": "Australia",
"Shortname": "scienceessentials10",
"MarketingSite": "http%3a%2f%2fwww.macmillan.com.au%2fsecondary%2fonix%2fall%2f6F597241EFC0E43DCA257791001CAFC0%3fopen%26div%3dSecondary%26cat%3dScience%253EAustralian%252BCurriculum%26template%3ddomSecondary%26ed%3dsite%2fseced31.nsf",
"Skin": "OneStopScience%20Green"},
"tag":"s_science"'
"tag":"s_maths"'
"tag":"s_arts",
{"uid": "5",}]})
I have three "tag" elements. but when we access the products.tag it gives always last element like:s_arts.
Is there any way to find out all the elements eg:s_science,s_maths,s_arts.
please help.
It is invalid json, your tag should be:
...,
"tag": ["s_science", "s_maths", "s_arts" ],
...
Then product.tag would be an array that you could access successfully
Regards
If you have multiple keys in the same object, you're going to get undefined behaviour. Only one will be preserved, and since pairs are not ordered, you can't guarantee which you'll get.
In short: the webservice is returning you faulty data. If multiple tags are expected, the service should return an array of values in the tag attribute:
...
"tag":["s_science", "s_maths", "s_arts"],
...
You need to send the tags as an array:
jsonp1332655154667({"products": [{"uid": "37",
"samsid": "hjk",
"name": "Science%20Essentials%2010%20AC%20edn",
"shortname": "scienceessentials10",
"description": "Science%20Essentials%2010%20ACE%20is%20the%20fourth%20in%20a%20series%20of%20four%20books%20designed%20for%20the%20National%20Curriculum.%20",
"generated": "3/25/2012%205:59:19%20AM",
"Description": "Science%20Essentials%2010%20ACE%20is%20the%20fourth%20in%20a%20series%20of%20four%20books%20designed%20for%20the%20National%20Curriculum.%20",
"PublishingCompany": "Macmillan%20Australia",
"Service": "OneStopScience",
"Service": "OneStopDigital",
"Icon": "http://curriculumplatform.s3.amazonaws.com/prod/icons/brain48.png",
"Country": "Australia",
"Shortname": "scienceessentials10",
"MarketingSite": "http%3a%2f%2fwww.macmillan.com.au%2fsecondary%2fonix%2fall%2f6F597241EFC0E43DCA257791001CAFC0%3fopen%26div%3dSecondary%26cat%3dScience%253EAustralian%252BCurriculum%26template%3ddomSecondary%26ed%3dsite%2fseced31.nsf",
"Skin": "OneStopScience%20Green"},
"tags": [
"s_science"'
"s_maths"'
"s_arts"
],
{"uid": "5",}]})
Then you reference them as data.tags[0], data.tags[1], data.tags[2].
if your response is in this format
YourResponse = {
"products" : [
{"uid" :"5", ......., "whtever":"someval"},
{"uid" :"6", ......., "whtever":"someval1"}
]
};
you can use this
$(YourResponse).each(
function(objName, objValue) {
console.log(objName); // wil get object name like uid, whtever
console.log(objValue); // wil get object's value
});
so to get Tags you will have to take Tuan's suggestion; send them in array

Categories