I am very new to AngularJS and I am trying to learn how to get deeper into a JSON object that has objects inside of objects and sometimes even arrays. This is a "simplified" version I am working with and I hope it will help me get a basic understanding so I can do the rest on my own.
json
values = {
"profile": {
"fields": {
"number-of-fields": "700",
"inside": [
"test1",
"test2"
],
"type": "test",
"values": "450"
}
},
"id": "12312312333645"
}
code
angular.forEach(values, function(value, key) {
console.log(key + ': ' + value);
// I know I need to loop inside of each object I beleieve
});
http://jsfiddle.net/ygahqdge/184/
The basics
Traverse object properties with a dot ., traverse array indexes with an index reference, [0|1|2|etc.].
What about your object?
var yoObject = {
"profile": {
"fields": {
"number-of-fields": "700",
"inside": [
"test1",
"test2"
],
"type": "test",
"values": "450"
}
},
"id": "12312312333645"
}
Get the inside values:
// object object object array
yoObject.profile.fields.inside.map(console.log, console) // ["test1", "test2"]
Get the id:
// object property
yoObject.id // "12312312333645"
Get all properties of the fields object:
Object.keys(yoObject.profile.fields) // ['number-of-fields', 'inside', 'type', 'values']
Get all values of the properies from above:
fields = yoObject.profile.fields
Object.keys(fields).map(key => console.log(fields[key])) // ["700", ["test1", "test2"], "test", "450"] // Note: Order isn't guaranteed
Just play about with things. Throw the object in the console and start to manually traverse it. Then try to loop over things.
Have fun!
Note: I tested none of that! :P
this is a question in regards on the right way to loop deep in JSON
objects – #user2402107
There's no right way. Sometimes you'll need to be fully dynamic, other times you can hardcode paths into nested properties and values.
Fiddle-Diddle
Nest as many times as you need:
angular.forEach(values, (value, key) => {
console.log("Value for", key, ":", value);
angular.forEach(value, (value, key) => {
console.log("Value for", key, ":", value);
angular.forEach(value, (value, key) => {
console.log("Value for", key, ":", value);
})
})
});
You can log the whole object to console. By using F12 tool, you can browse the object in the browser.
console.log(objectName);
angular.forEach works on arrays. lets suppose you have an array of objects as this
var values = [{
"profile": {
"fields": {
"number-of-fields": "700",
"interpertation": [
"whenever this is ready"
],
"type": "test",
"values": "450"
}
},
"id": "12312312333645"
},
{
"profile": {
"fields": {
"number-of-fields": "700",
"interpertation": [
"whenever this is ready"
],
"type": "test",
"values": "450"
}
},
"id": "12312312333645"
}]
you can explore each object and its properties like this
angular.forEach(values, function(value, key) {
console.log(value.profile.fields.values);
});
you can use . notation to access propertes
Related
below is part of my JSON response coming from an API
{
"totalCount": 2,
"customAttributes": [
{
"objectType": "OWNER",
"atrributeId": 215,
"attributeName": "DATELICENSEFIRSTISSUED",
"attributeDisplayName": "DATE LICENSE FIRST ISSUED",
"dataType": "DATE",
"inputValues": [],
"isGridEligible": "true",
"isInvoiceEligible": "false"
},
{
"objectType": "LOCATION",
"atrributeId": 217,
"attributeName": "DONOTRENEW",
"attributeDisplayName": "DO NOT RENEWS",
"dataType": "Value List",
"inputValues": [
{
"id": 5,
"value": "VEHICLELISTREQUIRED"
},
{
"id": 6,
"value": "STATESWITHRECIPROCITY"
}
],
"isGridEligible": "true",
"isInvoiceEligible": "false"
}
]
}
Here, I am binding customAttributes as grid data.
this.customFieldsService.getCustomFields(this.columnList, this.pageNumber, this.pageSize, null).subscribe(res => {
if(res){
this.cfData = res;
this.gridData = {
data: this.cfData.customAttributes,
total: this.cfData.totalCount
}
}
});
Here, my problem is with inputValues column, which comes as an array of objects. I need to convert it to comma seaparated values and then bind to grid data like
"inputValues": ["VEHICLELISTREQUIRED" "STATESWITHRECIPROCITY"]
I can ignore the "id" property as we are not using it at angular side. I tried using join method but not able to solve it within the nested array. Please suggest. Thanks.
In typescript it can be done with:
const joined: string = customAttribute.inputValues
.map(x => x.value) // [{value: 'VEHICLELISTREQUIRED'}, {value: 'STATESWITHRECIPROCITY'}]
.join(' ') // "VEHICLELISTREQUIRED" "STATESWITHRECIPROCITY"
const putIntoArray = [joined]; // ["VEHICLELISTREQUIRED" "STATESWITHRECIPROCITY"]
Of course you can put the joined string immediately into an array.
I am trying to get array key names to new array even if there is another array in array.
So far I am able to get all key names except key names which ones are in one level down.
I have existing array:
searchResult = [
{"id":1,
"name":"Duracell",
"manufacturer":"Duracell",
"model":"DC2400",
"type": {
"id":4,"type":"Nickel Metal Hydride","rechargeable":true
},
"size": {
"size":"AAA","shape":"Cylindrical"
},
"nominalCapacity":750,
"nominalVoltage":1,
"diameter":10,
"width":null,
"height":44,
"length":null,
"depth":null
},
{...},
{...}
]
And I am getting it as props and getting key names:
const formFields = Object.keys(this.props.searchResult[0])
console.log(formFields)
console.log output is:
["id",
"name",
"manufacturer",
"model",
"type",
"size",
"nominalCapacity",
"nominalVoltage",
"diameter",
"width",
"height",
"length",
"depth"]
It is missing this:
"type": {
"id", "type", "rechargeable"
},
"size": {
"size","shape"
}
So im expecting it to be something like this:
["id",
"name",
"manufacturer",
"model",
"type": {
"id", "type", "rechargeable"
},
"size": {
"size","shape"
},
"nominalCapacity",
"nominalVoltage",
"diameter",
"width",
"height",
"length",
"depth"]
UPDATE
From comment below which contains this link i used code:
const formFields = this.props.searchResult[0]
var keys = [];
for(var key in formFields) {
keys.push(key);
if(typeof formFields[key] === "object") {
var subkeys = getDeepKeys(formFields[key]);
keys = keys.concat(subkeys.map(function(subkey) {
return key + "." + subkey;
}));
}
}
console.log(keys)
console.log output is:
["id", "name", "manufacturer", "model", "type", "size", "nominalCapacity", "nominalVoltage", "diameter", "width", "height", "length", "depth"]
Still not what is expected. Totally same result
#NikKyriakides comment solved everything. Answer is in this question:
Get all keys of a deep object in Javascript
I have an object that can be with different properties (arrays/objects/etc).
I want to convert the object to be with each sub field encapsulated by array.
For example:
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
}
the head field including an object.
I want the object to be encapsulate in array like this:
"head": [{
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
}]
I figured out this is the possibility to keep the structure same for every item.
I also tryied to do so with interface but it made me problems since sometimes it's object and sometimes not so I want to keep the structure.
I would like to hear more if there's a better way to convert the object to a proper interface.
Thanks!
This will recursively check each value and make it an array if it isn't. Excluding keys you put in the keysToSkip array.
const obj = {
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
},
"alreadyArray": [
"val", "val2"
]
}
const keysToSkip = ["value"]
let depthFirstLoop = (obj) => {
Object.keys(obj).forEach((key) => {
if (typeof obj[key] === 'object' && obj[key] !== null) {
depthFirstLoop(obj[key]);
}
if (!Array.isArray(obj[key]) && !keysToSkip.includes(key)) {
obj[key] = [obj[key]]
}
});
};
depthFirstLoop(obj)
https://jsfiddle.net/9p7k64ec/26/
Generally you shouldn't change an object as you iterate over it. Better to create a new object.
const obj = {
"head": {
"text": "Main title",
"sub": {
"value": "next"
},
"place": "secondary"
}
}
var newObj = {}
for( key in obj ){
newObj[key] = [obj[key]]
}
I work with Autodesk Forge (node.js, javascript (worked with it a little), React (completely new !)).
I have a rectangle 3D object. At each corner is a point with real world coordinates (lat, lon, z).
These coordinates can be displayed with the property panel in the viewer.
I want to access them from the code, but I cannot find them anywhere.
At first, I thought they would be at :
window.NOP_VIEWER.model.getData().metadata
but nothing !
Here is a picture of what I can see in the viewer. Since I can see them in the property panel, I should be able to access them !
I tried to use this :
window.NOP_VIEWER.model.getBulkProperties('1',
function(properties){console.log(properties);},
function(error){console.log(error);})
It returns an amazingly long list of field names (if think that's it).
When I try to put it in a variable it returns 'undefined'. So I cannot access what is inside anyway.
Also tried getProperties() but I think I did not write it in the right way, it doesn't work either.
I also tried som GET request to find the object properties, but all I got was this :
{
"data": {
"type": "objects",
"objects": [
{
"objectid": 1,
"name": "Model",
"objects": [
{
"objectid": 2691,
"name": "Sols",
"objects": [
{
"objectid": 2692,
"name": "Sol",
"objects": [
{
"objectid": 2693,
"name": "Dalle en béton - 250 mm",
"objects": [
{
"objectid": 2694,
"name": "Sol [236041]"
}
]
}
]
}
]
},
{
"objectid": 2711,
"name": "Modèles génériques",
"objects": [
{
"objectid": 2712,
"name": "Point_Georeferencement",
"objects": [
{
"objectid": 2713,
"name": "Point_Georeferencement",
"objects": [
{
"objectid": 2714,
"name": "Point_Georeferencement [236831]"
},
{
"objectid": 2715,
"name": "Point_Georeferencement [236836]"
},
{
"objectid": 2716,
"name": "Point_Georeferencement [236843]"
},
{
"objectid": 2717,
"name": "Point_Georeferencement [236846]"
}
]
}
]
}
]
}
]
}
]
}
}
But I cannot find a way to access the points' names or their values !
Can anyone help with this, please ?
NOP_VIEWER is a global variable to access the current Viewer. From that you can call:
.getProperties(): this requires 1 dbId, an easy way to try it is with:
NOP_VIEWER.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, function (e) {
e.dbIdArray.forEach(function (dbId) {
NOP_VIEWER.getProperty(dbId, function (props) {
console.log(props)
})
})
});
.model.getBulkProperties(): this received an array of elements and just return the properties you specify:
NOP_VIEWER.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, function (e) {
viewer.model.getBulkProperties(e.dbIdArray, ['RefX', 'RefY'], function (elements) {
elements.forEach(function(element){
console.log(element);
})
})
});
And you may also combine it with .search() (see here) or by enumerating leaf nodes.
Considering the below bad model, as I am totally new to this.
{
"uid": "some-id",
"database": {
"name": "nameOfDatabase",
"collection": [
{
"name": "nameOfCollection",
"fields": {
"0": "field_1",
"1": "field_2"
}
},
{
"name": "nameOfAnotherCollection",
"fields": {
"0": "field_1"
}
}
]
}
}
I have the collection name (i.e database.collection.name) and I have a few fields to add to it or delete from it (there are some already existing ones under database.collection.fields, I want to add new ones or delete exiting ones).
In short how do I update/delete "fields", when I have the database name and the collection name.
I cannot figure out how to use positional operator $ in this context.
Using mongoose update as
Model.update(conditions, updates, options, callback);
I don't know what are correct conditions and correct updates parameters.
So far I have unsuccessfully used the below for model.update
conditions = {
"uid": req.body.uid,
"database.name": "test",
"database.collection":{ $elemMatch:{"name":req.body.collection.name}}
};
updates = {
$set: {
"fields": req.body.collection.fields
}
};
---------------------------------------------------------
conditions = {
"uid": req.body.uid,
"database.name": "test",
"database.collection.$.name":req.body.collection.name
};
updates = {
$addToSet: {
"fields": req.body.collection.fields
}
};
I tried a lot more but none did work, as I am totally new.
I am getting confused between $push, $set, $addToSet, what to use what not to?, how to?
The original schema is supposed to be as show below, but running queries on it is getting harder n harder.
{
"uid": "some-id",
"database": [
{ //array of database objects
"name": "nameOfDatabase",
"collection": [ //array of collection objects inside respective databases
{
"name": "nameOfCollection",
"fields": { //fields inside a this particular collection
"0": "field_1",
"1": "field_2"
}
}
]
}
]
}