Retrieve object with a key in javascript - javascript

I have following object, and if I want to retrieve only soccer, then I put soccer as follows,
sports['soccer'] does not bring it.
I wonder what I am missing here?
sports = [] ;
sports = [{
"soccer": {
"type": "foot",
"player": 11
},
"basketball": {
"type": "hand",
"player": 5
}
}]

Your current code creates an array with a single object. One solution is to just create an object instead:
sports = {
"soccer": {
"type": "foot",
"player": 11
},
"basketball": {
"type": "hand",
"player": 5
}
}
Now you can use sports.soccer or sports['soccer'] to access the soccer data.
If you really want an array of objects, you first need to subscript the array to get the first object:
sports[0].soccer
or
sports[0]['soccer']

var sports is an array with objects inside.
If you set it up like this:
sports = [] ;
sports = {
"soccer": {
"type": "foot",
"player": 11
},
"basketball": {
"type": "hand",
"player": 5
}
}
then you will be able to call sports['soccer'] or even sports.soccer.
Alternately, if you need it to remain an array, then you'll need to do more work.
Something like this should do the trick.
for(i=0; i < sports.length; i++) {
if("soccer" in sports[i]){
console.log(sports[i].soccer.type);
console.log(sports[i].soccer.player);
}
}
The console.logs represent whatever you want to do with the values

I think you really need to reiterate the basics of javascript a bit.
In JS we can create data structures on the fly with literal syntax. For example:
let normalArr = new Array();
let literalArr = [];
let normalObj = new Object();
let literalObj = {};
When you create arrays and objects with literal syntax you can initialize arrays with elements and object with properties on the fly. This is what exactly happened in your example:
sports = [{
"soccer": {
"type": "foot",
"player": 11
},
"basketball": {
"type": "hand",
"player": 5
}
}];
The code can be broken down in the following way:
You created an array which was stored in the sports variable using the array literal syntax (created an array on the fly).
You created 1 element of the array with the object literal syntax (creating an object on the fly)
This object (located inside the array) has 2 properties, soccer and basketball which are also object created with object literal syntax.
To access one of there objects you need to do the following:
const sports = [{
"soccer": {
"type": "foot",
"player": 11
},
"basketball": {
"type": "hand",
"player": 5
}
}];
// accessing the first element of the sports array
console.log(sports[0].soccer);
console.log(sports[0].basketball);

As others have pointed out, you have an array of objects, not a single object. You can use the find() method to find the element that has the soccer property, and then access that property.
var soccer = sports.find(s => 'soccer' in s)['soccer'];

Related

Get JSON keys in order

I have the below in a file and read as
var input = require("./mydata.json");
"User": {
"properties": {
"firstName": {
"type": "string",
"minLength": 1,
"maxLength": 50
},
"lastName": {
"type": "string",
"maxLength": 50
},
"middleName": {
"type": "string"
},
"title": {
"type": "string"
},
"language": {
"type": "string",
"default": "en-US"
}
}
}
I am using the below code to loop through the keys
var item = _.get(input, 'User');
var properties = item.properties;
var allKeys = _.keys(properties);
_.each(allKeys, function(key) {
});
Inside the each loop, I get the firstname, lastname etc, in the same sequence as in the input file.
I want to know if I will get it in order always?
Properties order in objects is not guaranteed in JavaScript; you need to use an Array to preserve it.
Definition of an Object from ECMAScript Third Edition (pdf):
4.3.3 Object
An object is a member of the
type Object. It is an unordered collection of properties each of which
contains a primitive value, object, or
function. A function stored in a
property of an object is called a
method.
Since ECMAScript 2015, using the Map object could be an alternative. A Map shares some similarities with an Object and guarantees the keys order:
A Map iterates its elements in insertion order, whereas iteration order is not specified for Objects.
Yes, If you want to change the order then you will need to sort or arrange the keys in a separate array and then loop on rearranged array.
Object.keys(input.User).sort();
// Will return all keys in sorted array.
Then , if you want to read value of each key following that order , just loop through that array :
Object.keys(input.User).sort().forEach((key,index)=>{
console.log('key :'+key+' , value :'+input.User[key]);
})

Keep order of objects inside a JSON String after they are parsed

I receive the following JSON string from an API function.
"Inbound": {
"callRelatedFields": ["ANI",
"DNIS"],
"objects": {
"Contact": [{
"displayName": "Name",
"apiName": "Name"
},
{
"displayName": "Email",
"apiName": "Email"
}],
"Account": [{
"displayName": "Account Name",
"apiName": "Name"
},
{
"displayName": "Phone",
"apiName": "Phone"
},
{
"displayName": "Fax",
"apiName": "Fax"
}],
"cnx__Phone__c": [{
"displayName": "Phone Name",
"apiName": "Name"
},
{
"displayName": "Phone Number Line 1",
"apiName": "cnx__Phone_Number_Line_1__c"
},
{
"displayName": "Phone Number Line 2",
"apiName": "cnx__Phone_Number_Line_2__c"
},
{
"displayName": "Type",
"apiName": "cnx__Type__c"
},
{
"displayName": "Location",
"apiName": "cnx__Location__c"
},
{
"displayName": "Call Manager",
"apiName": "cnx__Call_Manager__c"
},
{
"displayName": "Mac Address",
"apiName": "cnx__Mac_Address__c"
}]
},
"screenPopSettings": {
"screenPopsOpenWithin": "ExistingWindow",
"SingleMatch": {
"screenPopType": "PopToEntity"
},
"NoMatch": {
"screenPopType": "DoNotPop"
},
"MultipleMatches": {
"screenPopType": "DoNotPop"
}
}
}
The order of the objects inside "objects" is important!
But when i parse this JSON string with JSON.parse, the order of those objects is lost.
Is there any good way to keep the order of those objects after they are parsed.
I tried to manipulate the string and convert the whole "objects" into an array, but this turned out to become way too complicated and hacky.
I have a suspicion that the thing that makes you think the keys have changed order is that Chrome devtools show objects with their keys sorted in alphabetical order. Whereas if you use Object.keys() or the equivalent JS to manually iterate through the keys, you will find they come out in the order they were defined in the JSON string.
Here is the equivalent JS for Object.keys():
function objectKeys(obj) {
var keys = [];
if (!obj) return keys;
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
keys.push(key);
}
}
}
When I call this with the objects part of the parsed object I get the following array:
["Contact", "Account", "cnx__Phone__c"]
Unfortunately object properties are unordered in JavaScript so you shouldn't rely on being able to iterate over them in a particular sequence.
I would suggest accessing the properties by name in the order you need them, rather than just iterating over the list.
As per the JSON standard, an object is unordered. So if you care about the order "Contact", "Account", "cnx__Phone__c", put them in an array ([]).
Maybe it's enough to put the property names themselves in an array next to the .objects themselves, so that you still can access them by their names. Many structures are valid solutions.
This solution works only if the properties and the data does not contain one of these characters: {, } and :.
Maybe you replace the curly brackets to square brackets and ": to #",. After that, you can the JSON string parse and get all objects replaced by arrays. The reading is: first value is the property (marked with # at the end) and the second value is the value.
The replacement machanism shuld be improved, in particular the replacement of ":, which can sometimes be wrong, and the search of the curly brackets.
var json = '{"Inbound":{"callRelatedFields":["ANI","DNIS"],"objects":{"Contact":[{"displayName":"Name","apiName":"Name"},{"displayName":"Email","apiName":"Email"}],"Account":[{"displayName":"Account Name","apiName":"Name"},{"displayName":"Phone","apiName":"Phone"},{"displayName":"Fax","apiName":"Fax"}],"cnx__Phone__c":[{"displayName":"Phone Name","apiName":"Name"},{"displayName":"Phone Number Line 1","apiName":"cnx__Phone_Number_Line_1__c"},{"displayName":"Phone Number Line 2","apiName":"cnx__Phone_Number_Line_2__c"},{"displayName":"Type","apiName":"cnx__Type__c"},{"displayName":"Location","apiName":"cnx__Location__c"},{"displayName":"Call Manager","apiName":"cnx__Call_Manager__c"},{"displayName":"Mac Address","apiName":"cnx__Mac_Address__c"}]},"screenPopSettings":{"screenPopsOpenWithin":"ExistingWindow","SingleMatch":{"screenPopType":"PopToEntity"},"NoMatch":{"screenPopType":"DoNotPop"},"MultipleMatches":{"screenPopType":"DoNotPop"}}}}';
json = json.replace(/{/g, '[').replace(/}/g, ']').replace(/"\:/g, '#",');
json = JSON.parse(json);
document.write('<pre>' + JSON.stringify(json, 0, 4) + '</pre>');
#GregL is right the JSON parsed came in alphabetic or in case of a number in ascending order and to keep the order you'll need an incremented number logic like:
var position_in_array = 0
var name = 'screenPopSettings'
object[`${position_in_array}${name}`] = value
position_in_array += 1
The parseJson returns data in object form and object doesn't has index. So we should define custom index of data array, if we want to keep the array index.
Example:
$arr[0] = array(
'Contact'=>array(
'key1'=>'val',
)
);
$arr[1] = array(
'Account'=>array(
'key1'=>'val',
)
);
It will produce the output as per the array index originally defined before parseJson function call.

Add data to end of ko.observablearray

I'm trying to add data to the end of an observable array but it's just not working as expected. I bet it is something minor but I just can't get my head around it.
What I am doing:
self.businesses = ko.observableArray();
function Business(business) {
var self = this;
self.BusinessID = ko.observable(business.BusinessID );
self.Type = ko.observable(business.Type);
self.Location = ko.observable(business.Location);
}
/*ajax get array of businesses as follows:
[
{
"$id": "1",
"BusinessID ": 62,
"Type": "Data",
"Location": "Data"
},
{
"$id": "2",
"BusinessID ": 63,
"Type": "Data",
"Location": "Data"
},
{
"$id": "3",
"BusinessID ": 64,
"Type": "Data",
"Location": "Data",
} ]
*/
var mappedBusinesses = $.map(data, function (business) { return new Business(business) });
self.businesses(mappedBusinesses);
This all works as expected and the obersablearray is populated.
However if I go to add another business, it wont work. For example, if I call the ajax that returns this (as newBusiness):
{
"$id": "1",
"BusinessID ": 68,
"Type": "Data",
"Location": "Data"
}
and I do:
self.businesses().push(newBusiness);
It adds to the array as an "Object" not a Business. So I thought I would do:
var bus = $.map(newBusiness, function (business) { return new Business(business) });
self.businesses().push(bus);
But I get the error in the JS console "Uncaught TypeError: Cannot read property 'BusinessID' of null
So I made a new var and added the brackets: [] in and it adds to the observable array but not as a "Business" object but rather as an "Array[1]" object at the end and this doesn't function as per the others. Code as follows:
var newBus = {
BusinessID: newBusiness.BusinessID,
Type: newBusiness.Type,
Location: newBusiness.Location
}
var bus = $.map(newBus, function (business) { return new Business(business) });
self.businesses().push(bus);
As mentioned this adds to the observable array but doesn't actually add as a "business" object but rather as an "array[1]" object.
I bet it's something so basic but just can't get it working!
Argh I knew it would be simple!
It was posting the whole array to the ObservableArray...not just the object.
The fix:
self.businesses.push(newBusiness[0])
Had to add the [0] in to get it to push the actual data into the array, not the object!
Thanks for the answers!
You're evaluating the array with your push:
self.businesses().push(newBusiness);
Observable Arrays have their own array functions, you should just do this (no parens):
self.businesses.push(newBusiness);
See this page: http://knockoutjs.com/documentation/observableArrays.html

Complex JSON string Parsing in JavaScript

This is my sample JSON file , which im trying to parse and read the values ....
C = {{
"Travel": {
"ServiceProvider": {
"Name": "SRS",
"Rating": "3 stars",
"Rates": "Nominal",
"Features": {
"OnlineBooking": "Yes",
"SMS_Ticket": "No"
},
"UserDetails": {
"Name": "Jack",
"Age": "33",
"Gender": "Male"
}
},
"BusProvider": {
"Name": "SRS",
"Rating": "3 stars",
"Rates": "Nominal",
"Features": {
"OnlineBooking": "Yes",
"SMS_Ticket": "No"
},
"UserDetails": {
"Name": "Jack",
"Age": "33",
"Gender": "Male"
}
}
}
}
I'm pretty new to JS , and i need to access the nested elements in a generic fashion.
Im not able to extract the details properly. Im getting stuck accessing nested the child elements.
The problem for me is that i wont always know the names of the "key's' to acess them , the JSON will be dynamic , hence i need a generic mechanism to acess the nested child elements. The Nesting can go upto 3 -4 levels.
what notation do we use to access the key / value pairs when the nesting is deep.
Any Help would be appreciated.
ater desirializing your object you can do this
var resultJSON = '{"name":"ricardo","age":"23"}';
var result = $.parseJSON(resultJSON);
$.each(result, function(k, v) {
//display the key
alert(k + ' is the key)
}
you can do it using recursively offcourse like this - Link Here
the way is the same just adapt to your example
For dynamic access you can use brackets notation i.e. var json = {nonKnown: 1}; now you can access it like that:
var unknowPropertyName = "nonKnown";
var value = json[unknownPropertyName];
But if you can not even define dynamically name of the property, then you should use
for(variableName in json){
if(json.hasOwnProperty(variableName)){
console.log(variableName);
}
}
You should get the basic idea from this. Good luck

Traversing a JSON object

The data which I fetch from PHP page is like:
[{
"id": "1",
"name": null,
"startdate": "2012-07-20",
"starttime": "09:53:02",
"enddate": "2012-07-20",
"endtime": "09:54:10",
"duration": "01:00:00",
"feedbacks": [{
"id": "1",
"type": "1",
"content": "cont"
}],
"conditions": [{
"id": "1",
"dev_id": "1",
"mod_id": "2",
"sub_id": "3",
"to_be_compared_value": "1",
"comparison_type": "1"
}],
"actions": [{
"id": "1",
"dev_id": "1",
"mod_id": "1",
"sub_id": "1",
"target_action": "1"
}]
}]
Which way is easy, efficent and elegant to traverse this object? I used this two until this time. Can you tell me which one must be my choice, or can you give me an alternative? And why? I have a running version of my application and I'm reviewing now my own code, and I want to take some advices from you all.
Thanks in advance,
Methods I use before:
$.map
for(var i in obj)
One more to go, I will create a table from this data.
I would use jQuery's each() (or map() if I wanted to change the data)
I should add that you should also create a function which returns an object (possibly even with some utility methods), since your data isn't very JS-friendly right now. Those dates and times, those ID's as strings.
Example:
function cleanMyObject(object){
var cleanFeedbacks = function(feedbacks){
/* ... */
return feedback;
};
object.start = /* transform date and time strings to datetime object ...*/
object.end = /*...*/
/*...*/
$.map(object.feedbacks,cleanFeedbacks);
/* cleanup the remaining objects... */
return object;
}
$.map(receivedData, cleanMyObject);
// cleanMyObject() returns the modified object so $.map will clean everything in your array.
I prefer to use http://underscorejs.org/ for things like this. It has a lot of useful functions for objects, collections etc.
If the data you are recieving doesn't change, just parse the object and use the keys you need.
All browsers I'm aware of have a function called JSON.parse to convert a JSON string into a JS object.
What I'm trying to say is: Don't be lazy, you aren't gaining any benefits from writing a "general" function if your object will always provide the same data, and there is little to no chance you can use that function again with a different object.
var myobj= JSON.parse(phpJSONstring);
var feedbacks= myobj["feedbacks"];
//do something with feedbacks
var conditions= myobj["conditions"];
//do something with conditions
etc
You can transform the json string in a javascript object, and then access the object like this:
var obj = jQuery.parseJSON(jsonString);
alert('Id='+obj.id);
var feedbackList = obj.feedbacks;
for (var i=0; i<feedbackList.length; i++) {
...
}
Reference to jQuery.parseJSON: http://api.jquery.com/jQuery.parseJSON/

Categories

Resources