ForEach Loop JSON AngularJS Object in Object - angularjs

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

Angular - Convert objects in a nested array into comma seapared values before binding to grid

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.

How to get array key names even if in object there is another 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

How to encapsulate object fields to be in array

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]]
}

Find custom point coordinates with Forge

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.

Add new object inside array of objects, inside array of objects in mongodb

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"
}
}
]
}
]
}

Resources