get data through JSON - javascript

I have some JSON below, What I would like to do is iterate through the JSON file and pull out the 'title' element and make a list. Could anybody help?
{ "slides" : {
"sl_0_0" : {
"title" : "Slide 0-0",
"copy" : "Copy for slide 0-0",
"link" : "sl_0_0.html"
},
"sl_1_0" : {
"title" : "Slide 1-0",
"copy" : "Copy for slide 1-0",
"link" : "sl_1_0.html"
},
"sl_1_1" : {
"title" : "Slide 1-1",
"copy" : "Copy for slide 1-1",
"link" : "sl_1_1.html"
},
"sl_2_0" : {
"title" : "Slide 2_0",
"copy" : "Copy for slide 2_0",
"link" : "sl_2_0.html"
},
"sl_2_1" : {
"title" : "Slide 2_1",
"copy" : "Copy for slide 2_1",
"link" : "sl_2_1.html"
},
"sl_2_2" : {
"title" : "Slide 2_2",
"copy" : "Copy for slide 2_2",
"link" : "sl_2_2.html"
}
}
}

You treat a JSON object just as you would any other javascript object. So, you can interate through it using a for loops like this:
var jsonObj = { /* your JSON object here */ };
for ( var id in jsonObj.slides ) {
var slide = jsonObj.slides[id];
var title = slide.title; //etc.
/* Now you can build your list */
}

Related

"Evaluate" Function that is stored in MongoDB Server

My collection looks like this:
> db.projects_columns.find()
{ "_id" : "5b28866a13311e44a82e4b8d", "checkbox" : true }
{ "_id" : "5b28866a13311e44a82e4b8e", "field" : "_id", "title" : "ID", "sortable" : true }
{ "_id" : "5b28866a13311e44a82e4b8f", "field" : "Project", "title" : "Project", "editable" : { "title" : "Project", "placeholder" : "Project" } }
{ "_id" : "5b28866a13311e44a82e4b90", "field" : "Owner", "title" : "Owner", "editable" : { "title" : "Owner", "placeholder" : "Owner" } }
{ "_id" : "5b28866a13311e44a82e4b91", "field" : "Name #1", "title" : "Name #1", "editable" : { "title" : "Name #1", "placeholder" : "Name #1" } }
{ "_id" : "5b28866a13311e44a82e4b92", "field" : "Name #2", "title" : "Name #2", "editable" : { "title" : "Name #2", "placeholder" : "Name #2" } }
{ "_id" : "5b28866a13311e44a82e4b93", "field" : "Status", "title" : "Status", "editable" : { "title" : "Status", "type" : "select", "source" : [ { "value" : "", "text" : "Not Selected" }, { "value" : "Not Started", "text" : "Not Started" }, { "value" : "WIP", "text" : "WIP" }, { "value" : "Completed", "text" : "Completed" } ], "display" : "function (value, sourceData) { var colors = { 0: 'Gray', 1: '#E67C73', 2: '#F6B86B', 3: '#57BB8A' }; var status_ele = $.grep(sourceData, function(ele){ return ele.value == value; }); $(this).text(status_ele[0].text).css('color', colors[value]); }", "showbuttons" : false } }
You can see that in the very last document that I have stored a function as text.Now the idea is that I will request this data and will be in an Javascript Array format.
But I want to be able to have my function without the quotes! You can see that simply evaluating it will not work because I need to have it still needs to be inside of the object ready to be executed when the array is used.
How can I achieve this?
Thanks for any help!
There are two possible solutions, but neither particularly safe and you should strongly consider why you need to store functions as strings in the first place. That being said, you could do two things.
The simplest is to use eval. To do so, you would have to first parse the object like normal, and then set the property that you want to the result of eval-ing the function string, like so:
// Pass in whatever JSON you want to parse
var myObject = JSON.parse(myJSONString);
// Converts the string to a function
myObject.display = eval("(" + myObject.display + ")");
// Call the function with whatever parameters you want
myObject.display(param1, param2);
The additional parentheses are to make sure that evaluation works correctly. Note, that this is not considered safe by Mozilla and there is an explicit recommendation not to use eval.
The second option is to use the Function constructor. To do so, you would need to restructure your data so that you store the parameters separately, so you could do something like this:
var myObject = JSON.parse(myJSONString);
// displayParam1 and displayParam2 are the stored names of your parameters for the function
myObject.display = Function(myObject.displayParam1, myObject.displayParam2, myObject.display)
This method definitely takes more modification, so if you want to use your existing structure, I recommend eval. However, again, make sure that this is absolutely necessary because both are considered unsafe since outside actors could basically inject code into your server.

Add new element to array with setState

How to add new element to array with setState
I have this data
this.state = {
items : [
{ "id" : "324", "parent" : "qqqq", "text" : "Simple root node" },
{ "id" : "24", "parent" : "dwdw", "text" : "Root node" },
{ "id" : "55", "parent" : "ajson2", "text" : "Ch" },
{ "id" : "9866", "parent" : "ajson2", "text" : "oiiojio" },
]
}
I'm mapping the data
{this.state.items.sort((a,b) => a.newID < b.newID).map((item)=>
<ul>
<li key={item.id}><span>ID: </span>{item.id} <span>parent: </span>{item.parent} <span>text: </span>{item.text}</li>
</ul>
)}
and then I'm sorting the data by newID That I need to create it with setState
this.setState(prevState=>({newData: [...prevState.items, this.props.account.info]}));
How can I create new element with this.props.account.info add somthing like i++ I don't know actually
this.props.account.info It's adding data like
{ "id" : "324", "parent" : "qqqq", "text" : "Simple root node" }
So I need to add an element inside this will be like
{ "newID": "1", "id" : "324", "parent" : "qqqq", "text" : "Simple root node" }
So if you want to add "newID" field in the object, there is a way to do this using object spread operator.
{...this.props.account.info, "newID":"1"}
This will give you a new object with the "newID" field added with "1" as its value associated with it.
This is a shorthand for this:
Object.assign({}, this.props.account.info, {"newID": "1"});

Find and replace only certain fields in a document

I have a mongo document like so:
{
"_id" : "EimL8Hf5SsCQKM7WP",
"enable" : "no",
"collector" : [
{
"name" : "prod",
"enable" : "no",
"transport" : {
"address" : {},
"port" : "8000",
"protocol" : "http-secure"
},
"authentication" : {},
"notify-syslog" : "yes"
},
{
"name" : "test",
"enable" : "no",
"transport" : {
"address" : {},
"port" : "8000",
"protocol" : "http-secure"
},
"authentication" : {},
"notify-syslog" : "yes"
}
],
"misc" : {
"createdBy" : "someuser",
"updatedBy" : "someuser",
}
}
I display certain fields of the mongo document as an autoform to the user so that they can be edited. Since the other fields are hidden, the outcome of the form will only contain the fields that were exposed.
I end up with a modified document object like so: (keep an eye on the "name" fields)
{
"enable" : "no",
"collector" : [
{
"name" : "someohername",
},
{
"name" : "anothername",
}
],
"misc" : {
"createdBy" : "someuser",
"updatedBy" : "anotheruser",
}
}
My current requirement is to somehow merge both the documents together such that the initial document has all fields of the modified document, along with it's fields.
Outcome:
{
"_id" : "EimL8Hf5SsCQKM7WP",
"enable" : "no",
"collector" : [
{
"name" : "someothername",
"enable" : "no",
"transport" : {
"address" : {},
"port" : "8000",
"protocol" : "http-secure"
},
"authentication" : {},
"notify-syslog" : "yes"
},
{
"name" : "anothername",
"enable" : "no",
"transport" : {
"address" : {},
"port" : "8000",
"protocol" : "http-secure"
},
"authentication" : {},
"notify-syslog" : "yes"
}
],
"misc" : {
"createdBy" : "someuser",
"updatedBy" : "anotheruser",
}
}
If you notice above, only the name field has been updated whilst retaining the remaining fields.
I tried to directly update the document using collection.update({id}, $set:{<<modified_docuemnt}}); but it is replacing the entire collector field with what is passed in the $set
How exactly do I go about this? It does not matter if I'm doing the changes directly in mongodb or as a JSON object using javascript.

How to back and forth in array of data?

I have a following data which I am iterating on paragraph, which performs different task in different steps. I am not getting how to load selected view and controller in angular and make current as active.
http://prntscr.com/fisflz
[{
"0" : {
"name" : "Select Event"
},
"1" : {
"name" : "Connect"
},
"2" : {
"name" : "Configure"
},
"3" : {
"name" : "Test"
},
"4" : {
"name" : "Finish"
}
}]
Hint will appreciable.
Thanks

How can I create a dynamic list of routes from JSON?

I have a JSON file containing information for a tile based navigation app which uses the Router. Each tile could be a link directly to an external application, or it could contain subtiles which are displayed when the tile is clicked. Each of these could have their own subtiles, and so on. The JSON will eventually be delivered by an OData service so the app needs to dynamically create the navigation as it may change.
How can I implement the Router to have the URL looking like #tile1/tile1-1/tile1-1-3 which would indicate the user clicked on the first tile, which went to a screen where they clicked on the first tile there, followed by another screen on which they clicked the third tile? That route would, when coming from a bookmark, load the screen with subtiles from the tile1-1-3 node from the JSON.
The names 'tile1-1-3' etc are only to help visualise the position of the tile for this example. In the real version the names won't indicate the position in the tree, they will be more like #MyApps/MyApprovalApps.
I have a recursive function which crawls through every node and generates an individual route, but I'm unsure how to add the dynamic pattern like {tile}/{subtile}/{subtile} and also the parent route which I think will be needed to navigate between the levels properly.
I have a Home.view.xml which displays the top level tiles, and a Page1.view.xml for the rest of the levels of subtiles. Is this correct? How can I create the views dynamically if not?
Hopefully my goal is clear, I can elaborate more if needed.
Recursive function which creates the routes:
createRoutes: function(aData, oRouter){
for(var i=0; i<aData.length; i++){
oRouter.addRoute({name: aData[i].id,
pattern: aData[i].title,
view: "Page1"}); //parent?
if(aData[i].subtiles.length > 0){ // has subtiles
this.createRoutes(aData[i].subtiles, oRouter);
}
}
}
JSON:
{
"TilesCollection" : [
{
"id" : "tile1",
"title" : "tile1",
"target" : "#",
"subtiles" : [
{
"id" : "tile1-1",
"title" : "tile1--1",
"target" : "#",
"subtiles" : []
}
]
},
{
"id" : "tile2",
"title" : "tile2",
"target" : "#",
"subtiles" : [
{
"id" : "tile2-1",
"title" : "tile2--1",
"target" : "#",
"subtiles" : []
},
{
"id" : "tile2-2",
"title" : "tile2--2",
"target" : "#",
"subtiles" : []
},
{
"id" : "tile2-3",
"title" : "tile2--3",
"target" : "#",
"subtiles" : [
{
"id" : "tile2-3-1",
"title" : "tile2--3--1",
"target" : "#",
"subtiles" : []
},
{
"id" : "tile2-3-2",
"title" : "tile2--3--2",
"target" : "#",
"subtiles" : []
}
]
}
]
},
{
"id" : "tile3",
"title" : "tile3",
"target" : "#",
"subtiles" : []
},
{
"id" : "tile4",
"title" : "tile4",
"target" : "#",
"subtiles" : [
{
"id" : "tile4-1",
"title" : "tile4--1",
"target" : "#",
"subtiles" : []
}
]
}
]
}
How about this?
createRoutes: function(aData, oRouter, sParentPattern, iViewLevel) {
iViewLevel = iViewLevel || 0;
for (var i=0; i<aData.length; i++) {
var sPattern = sParentPattern ? sParentPattern +"/"+ aData[i].title : aData[i].title;
oRouter.addRoute({
name: aData[i].id,
pattern: sPattern,
view: "Page1",
viewLevel : iViewLevel
});
if (aData[i].subtiles.length > 0) {
this.createRoutes(aData[i].subtiles, oRouter, sPattern, iViewLevel+1);
}
}
}
In this example you just use the pattern to build the parent-child relationship just as you suggested.
If I understand you correctly you're asking how can you represent th clicking route as a string, whcih you can pass as prt of a URL ?
Referring to the tile IDs...
You could pass the text in as a JS array of objects I guess (ie include this JSON as part of the URL) :
a.b.com/xyz?route=[{"tile1-1",{"tile1-1"}},{"tile2",{"tile2-3"}}]
meaning they clicked tile1 -> tile1-1 -> tile2 -> tile2-3
Alternatively if the Ids are potentially secure or something, you could pass it by index no. as it's an aray :
a.b.com/xyz?route=[{0,{0}},{0,{2}}]
Then eval the passed string to turn it directly into Javascript object.
Or if you're concerned about people hacking, write a routine to interpret it.
(same clicking as above) - this relies on the tile arrangement never changing though.

Categories

Resources