Javascript - parse JSON looking for object string - javascript

I'm creating a webpage which displays data which I have parsed from a JSON. I am using 2 JSON files. One I can parse with no problems however, the second I am struggling with.
I want to be able to parse the JSON looking for a specific object string and return all the other object strings within the same dictionary.
The layout of the JSON is:
{
"example":[
{
"Area":"Inside",
"Player":"1",
"Status":1,
"Start_Time":"2016-12-21",
"End_Time":"2016-12-22",
},
{
"Area":"Outside",
"Player":"1",
"Status":1,
"Start_Time":"2016-12-24",
"End_Time":"2016-12-25",
},
{
"Area":"Outside",
"Player":"2",
"Status":1,
"Start_Time":"2016-12-26",
"End_Time":"2016-12-28",
}
]
}
I want to say
if (player=="1") {//show ALL areas and start and end time}
//output should be something like: Area: Inside, Player: 1, Status: 1, Start_Time: 'Time', End_Time: 'Time', Area: Outside, Player: 1, Status: 1, Start_Time: 'Time', End_Time: 'Time'
I am trying to parse the JSON in javascript, this is how I am parsing the other JSON:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
var dateTime = myObj.Date;
}
};
xmlhttp.open("GET", "http://web/server/file.json", true);
xmlhttp.send();
Any help is appreciated.

You may want to try filter
myObj.example.filter(obj => obj.Player == "1")
// 0: {Area: "Inside", Player: "1", Status: 1, Start_Time: "2016-12-21", End_Time: "2016-12-22"}
// 1: {Area: "Outside", Player: "1", Status: 1, Start_Time: "2016-12-24", End_Time: "2016-12-25"}

Using forEach loop
var a={
"example":[
{
"Area":"Inside",
"Player":"1",
"Status":1,
"Start_Time":"2016-12-21",
"End_Time":"2016-12-22",
},
{
"Area":"Outside",
"Player":"1",
"Status":1,
"Start_Time":"2016-12-24",
"End_Time":"2016-12-25",
},
{
"Area":"Outside",
"Player":"2",
"Status":1,
"Start_Time":"2016-12-26",
"End_Time":"2016-12-28",
}
]
};
a.example.forEach(e=>e.Player=="1" && e.Area=="Inside"?console.log(e):false)

You really have two problems here: fetching the JSON and then parsing it to find the data you're interested in. The following snippet takes care of the first task with fetch() (the modern successor to XMLHttpRequest) and the latter task with Array.prototype.filter.
Note that if you're not using a modern javascript environment, this solution will fail. Also note that this could could be improved using the newish async/await. I excluded them for simplicity's sake.
fetch("http://web/server/file.json") // supported in modern browsers.
.then(res => res.json()) // parses into JSON. Fails if given improper json
.then(data => {
console.log(data.example.filter(el => el.Player === 1)); // filter returns an array with only elements that meet the condition
});

Related

Is it possible to ignore project() programmatically for mongodb find()?

I'm using project() to get specific fields from my mongodb query (nodeJS mongoDB driver). But in my case I need the projection only in specific cases.
So if useProjection is false, the complete datasets should be returned. I handled it this way:
if (useProjection) {
return Content.find(query)
.project({
title: 1,
type: 1,
category: 1
})
.toArray()
}
return Content.find(query).toArray()
Is it possible to tell project() to return everything as it wouldn't be used, so it would become simpler as:
return Content.find(query)
.project(useProjection && {
title: 1,
type: 1,
category: 1
})
.toArray()
With this, I assume project(undefined) would return the complete dataset. I do not find anythin in the docs, if {} or undefined would be the correct parameter - if it is possible at all.
I don't think there is any option to do in project(), but you can try query builder approach,
let q = Content.find(query);
if (useProjection) q.project({ title: 1, type: 1, category: 1 });
return q.toArray();

Iterating over nested data JS

I'm a little bit new to programming and very new to JS so I apologize for the beginner question.
I'm trying to iterate through this data and get each tracks name and artist but I'm having an issue. Currently I'm trying something like this.
If anybody has any insight or suggestions I would appreciate it greatly.
I'm using a rails backend with JS frontend. Thank you!
function selectTracks(){
fetch(BACKEND_URL)
.then(response => response.json())
.then(playlist => {
playlist.data.forEach(playlist => {
`<h4> ${playlist.attributes.track.name}</h4>
<h4>${playlist.attributes.track.artist}></h4> `
// let newPlaylist = new Playlist(playlist, playlist.attributes)
console.log(fetch)
// document.getElementById("playlist-container").innerHTML += newPlaylist.renderPlaylistCard();
debugger
}
)}
)
}
My serializer looks like this
{
data: [
{
id: "1",
type: "playlist",
attributes: {
name: "Country Songs",
id: 1,
track_id: 10,
track: {
id: 10,
name: "First Song",
artist: "Randy",
created_at: "2020-06-17T02:09:07.152Z",
updated_at: "2020-06-17T02:09:07.152Z"
}
},
relationships: {
track: {
data: {
id: "10",
type: "track"
}
}
}
}
]
}
You need to replace forEach with map. The 'forEachloop doesn't return anything. But themapmethod return an array. (An array of HTML elements in your case
fetch(BACKEND_URL)
.then(response => response.json())
.then(playlist => {
return playlist.data.map(playlist => {
`<h4> ${playlist.attributes.track.name}</h4>
<h4>${playlist.attributes.track.artist}></h4> `
// let newPlaylist = new Playlist(playlist, playlist.attributes)
console.log(fetch)
// document.getElementById("playlist-container").innerHTML += newPlaylist.renderPlaylistCard();
debugger
}
)}
)
Your code technically works assuming that the BACKEND_URL is correct and the json is valid. But, in its current state, it doesn't do anything with the data. If you output the h4 tags, for instance, you should see them written to the screen.
document.write(
`<h4> ${playlist.attributes.track.name}</h4>
<h4>${playlist.attributes.track.artist}</h4> `
)
Or alternatively you could log the values out to prove that you are processing the data correctly:
console.log(playlist.attributes.track.name, playlist.attributes.track.artist)
If not, the next thing to check is the validity of your json. I'm assuming that you copied your json from the browser which will strip some quotes for readability. View the source to ensure that the key names are correctly wrapped in quotes like this:
{
"data": [
{
"id": "1",
"type": "playlist",
"attributes": {
"name": "Country Songs",
...
If you are using ActiveModel Serializers, they should be formatted correctly.
If your json is valid and you can write the h4 tags to the page with the correct data in them, then the problem probably lies in your Playlist class.
Another handy tool for diagnosing fetch() problems is in Chrome Developer Tools. Go to the Network and click the XHR filter. This will allow you to inspect the fetch request and see if the response is valid and the data is what you expect. Other browsers have a similar feature.

How to convert object in array js [duplicate]

This question already has answers here:
Parse JSON in JavaScript? [duplicate]
(16 answers)
Closed 4 years ago.
I very new to programming and I can't find the solution of my issue, can you give me the solution please?
I have this JSON file:
{
"groups": "[{ id: 1, title: 'group 1' }, { id: 2, title: 'group 2' }]"
}
And I need something like this in my js (but i want import my JSON to get array like this) :
const groups = [{ id: 1, title: 'group 1' }, { id: 2, title: 'group 2' }]
I don't know how to do without using jQuery.
I already tried with this:
const json = require('./test.json');
This code returns an object:
It's almost what I want but it didn't work when I use it in my code because I don't want an object but and array like I said above.
How can achieve this?
The value of groups is not valid JSON: string values should be surrounded by double-quote marks, and so should keys. The file with valid JSON in that string would look like this:
{
"groups": "[{ \"id\": 1, \"title\": \"group 1\" }, { \"id\": 2, \"title\": \"group 2\" }]"
}
Of course if you have control over the creation of this file, it would be better to have this value as part of the native JSON content, rather than JSON-in-a-string-inside-JSON. If that's not possible, you will need to correct the quoting in the string yourself, which can be done with a couple of Regular Expression replacements.
/* obj is the object in the JSON file */
var json_str = obj.groups.replace(/'/g,"\"").replace(/([a-z]+)\:/g,"\"$1\":");
var groups = JSON.parse(json_str);
Alternatively, although the string is not valid JSON it is a valid Javascript expression, so if the contents of the file are trustworthy, you can also do it with eval:
var groups = eval(obj.groups);
I just need to fill my array "groups" like that :
[{ id: 1, title: 'group 1' }, { id: 2, title: 'group 2' }]
with a json file and without jquery
Since I didn't notice the "without jQuery" in the original question, here is a new answer:
var request = new XMLHttpRequest();
request.open('GET', './test.json', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var data = JSON.parse(request.responseText);
} else {
// We reached our target server, but it returned an error
}
};
It does two things:
1. Loads the json file
2. Parses the loaded string into a javascript object.
Before you can even do anything with your JSON file, you need to load it. jQuery has a shortcut, which will even automatically parse the JSON-string into a native JS object for you:
$.getJSON('./test.json', function(data) {
console.dir(data);
});
https://api.jquery.com/jquery.getjson/
if you can't edit original text, you need replace ' to " and then did JSON.parse(json.groups);
otherwise you can change a little your json like this:
JSON.parse('[{ "id": 1, "title": "group 1" }, { "id": 2, "title": "group 2" }]')
be careful with " and ' parentheses
{
"key":"string"
}
string with defined with ' parentheses not valid
in JSON keys must be to in "" parentheses
You can parse the object to an array this way:
Object.values(YOUR_OBJECT)
docs: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/values

Couchdb filtering results using reduce function and startkey/endkey

I have documents that set up like this:
{ _id: 1, name: "A", timestamp: 1478115739, type: "report" }
{ _id: 2, name: "B", timestamp: 1478103721, type: "transmission" }
{ _id: 3, name: "C", timestamp: 1473114714, type: "report" }
I am trying to create a view that only returns the documents within a specific timestamp range. And I would love to be able to filter by type as well.
Here is my javascript call for the the data:
db.query('filters/timestamp_type', { startKey: 1378115739, endKey: 1478115740 })
.then(function(resp) {
//do stuff
})
I only know where to put the starting and ending timestamps. I'm having a hard time figuring out where I would say I only want the report's returned.
In addition, this is my map function for my filter, which is obviously not even close to being complete. I'm not sure how I even access the start and end key.
function (doc) {
if(type == "report" && startKey >= doc.timestamp && endKey <= doc.timestamp)
emit(doc._id, doc.name);
}
My question remains:
Where do I retrieve the start and end key's in my map function?
How can I add an addition type filter for only getting a specific type of report.
I know I might need to use a reduce function but it's going over my head. Here is the default reduce function but I'm not sure how it would work with the map function.
function (keys, values, rereduce) {
if (rereduce) {
return sum(values);
} else {
return values.length;
}
}
Thank you, any help or guidance would be appreciated.
Use a map function to get reports by a specific type-
function(doc) {
if(doc.type == "report") {
emit(doc.timestamp, doc);
}
}
when the view is queried, only documents with the type 'report' will be returned. If you need to support multiple types, you will have to create a new view for each type.
To query this view and specify the start & end timestamps, just add them to your query-
curl -XGET http://localhost:5984/<your-database>/_design/docs/_view/<your-view-name>?startkey="1478115739"&endkey="1478103721"
Reference

Django Rest Framework: Loop inside JSON OBJECT

Hi Guys I'm new to Django and Python... I'm using REST Framework to develop some webservices. I want to loop through all the orders of a JSON item. The request from javascript is done in this way:
function TestDjangoPostWithNoCsrlTokenAndWithMultipleObjectsJson() {
var JSONObject = new Object();
JSONObject.Orders = [];
JSONObject.Orders.push({ id: 1, Name: 'Name1', Description: 'Description1' });
JSONObject.Orders.push({ id: 2, Name: 'Name2', Description: 'Description1' });
JSONObject.Orders.push({ id: 3, Name: 'Name3', Description: 'Description1' });
console.log(JSON.stringify(JSONObject));
$.ajax
({
type: "POST",
url: URL_PostOrdersMultipleObjects,
headers: {
"Authorization": "Basic " + btoa("xxx" + ":" + "xxx")
},
data: JSONObject,
dataType: 'json',
success: function (data, status, xhr) {
console.log(JSON.stringify(data));
if (xhr.readyState == 4) {
if (xhr.status == 201) {
console.log("Created");
}
} else {
console.log("NoGood");
}
},
complete: function (xhr) {
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr.status);
console.log(thrownError);
}
});
}
On Django side, I have...
#api_view(['GET', 'POST'])
def JSONPostTest(request):
if request.method == 'POST':
stream = io.BytesIO(request.body)
obj = JSONParser().parse(stream)
for order in obj['Orders']: # First Example
serializer = QASerializer(data=order)
if serializer.is_valid():
serializer.save()
else :
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return Response('OK', status=status.HTTP_201_CREATED)
else:
return Response('OK', status=status.HTTP_201_CREATED)
If In javascript i stringify my object before to send it the above code works fine. The problems is when I don't stringify.
If I stringify
request.body =
b'{"Orders":[{"id":1,"Name":"Name1","Description":"Description1"},{"id":2,"Name":"Name2","Description":"Description2"},{"id":3,"Name":"Name3","Description":"Description3"}]}'
if I don't stringify
request.body
b'Orders%5B0%5D%5Bid%5D=1&Orders%5B0%5D%5BName%5D=Name1&Orders%5B0%5D%5BDescription%5D=Description1&Orders%5B1%5D%5Bid%5D=2&Orders%5B1%5D%5BName%5D=Name2&Orders%5B1%5D%5BDescription%5D=Description1&Orders%5B2%5D%5Bid%5D=3&Orders%5B2%5D%5BName%5D=Name3&Orders%5B2%5D%5BDescription%5D=Description1'
and
request.data
<QueryDict: {'Orders[1][Description]': ['Description1'], 'Orders[2][id]': ['3'], 'Orders[0][Name]': ['Name1'], 'Orders[0][Description]': ['Description1'], 'Orders[2][Description]': ['Description1'], 'Orders[1][id]': ['2'], 'Orders[0][id]': ['1'], 'Orders[1][Name]': ['Name2'], 'Orders[2][Name]': ['Name3']}>
I can stringify no problem on that. But I want to understand if it's possible to obtain the same result without stringifing starting from the QueryDict I have.
Thank you
You've not only constructed your JSON object in an unnecessarily verbose and complex way, you're also using the wrong data structure. If you want to iterate something, it should be an array (which maps to a list in Python), not an object (which maps to a dict). Your JS code should look like this:
JSONObject.Orders = [];
JSONObject.Orders.push({id: 1, Name: 'Name1', Description: 'Description1'});
JSONObject.Orders.push({id: 2, Name: 'Name2', Description: 'Description1'});
JSONObject.Orders.push({id: 3, Name: 'Name3', Description: 'Description1'});
(You could actually make that more compact by defining the objects inline with the array, but this is at least clearer for now.)
Now, it's simple to iterate in Python:
for obj in jsondata['Orders']:
...
Since you write you have a Serializer for Order I assume it is also a model on your backend and you would like to store it in the database. In that case I would not bother to manually deserialize the list of orders but let django-restframework unpack the nested child objects along with the parent.
Have a look here: https://stackoverflow.com/a/28246994/640916

Categories