Combining multiple json and displaying it in Angular UI Grid - angularjs

i am trying to get json from multiple source and want to display it in the single Angular UI grid. in all these source first field is common .
Data format :
Source :1
var one=[
{ col1: "Heading 1", col2: "First 12", col3: "First 13"},
{ col1: "Heading 2", col2: "First 22", col3: "First 23"},
{ col1: "Heading 3", col2: "First 32", col3: "First 33"},
{ col1: "Heading 4", col2: "First 42", col3: "First 43"},
{ col1: "Heading 5", col2: "First 52", col3: "First 53"}
];
Source: 2
var two=[
{ col1: "Heading 1", col2: "Second 12", col3: "Second 13"},
{ col1: "Heading 2", col2: "Second 22", col3: "Second 23"},
{ col1: "Heading 3", col2: "Second 32", col3: "Second 33"},
{ col1: "Heading 4", col2: "Second 42", col3: "Second 43"},
{ col1: "Heading 5", col2: "Second 52", col3: "Second 53"}
];
I want it to be displayed in gird like this
Source:
var app = angular.module('plunker', ['ui.grid', 'ui.grid.selection']);
app.controller('MainCtrl', ['$scope', 'uiGridConstants', function($scope, uiGridConstants) {
var one=[
{ col1: "Heading 1", col2: "First 12", col3: "First 13"},
{ col1: "Heading 2", col2: "First 22", col3: "First 23"},
{ col1: "Heading 3", col2: "First 32", col3: "First 33"},
{ col1: "Heading 4", col2: "First 42", col3: "First 43"},
{ col1: "Heading 5", col2: "First 52", col3: "First 53"}
]; 1
1
var two=[
{ col1: "Heading 1", col2: "Second 12", col3: "Second 13"},
{ col1: "Heading 2", col2: "Second 22", col3: "Second 23"},
{ col1: "Heading 3", col2: "Second 32", col3: "Second 33"},
{ col1: "Heading 4", col2: "Second 42", col3: "Second 43"},
{ col1: "Heading 5", col2: "Second 52", col3: "Second 53"}
];
var finalObj = {
"firstData":one,
"secondData":two
}
console.log("finalObj"+JSON.stringify(finalObj));
$scope.gridOptions = {
columnDefs: [
{field: 'firstData.col1', displayName: 'Column 1', width: 175},
{field: 'firstData.col2', displayName: 'Column 2', width: '*'},
{field: 'firstData.col3', displayName: 'Column 3', width: 120},
{field: 'secondData.col2', displayName: 'Column 4', width: '*'},
{field: 'secondData.col3', displayName: 'Column 5', width: 120}
],
enableRowSelection: true,
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
}
};
$scope.gridOptions=finalObj;
}]);
Code : see the attaced Plunkr http://plnkr.co/edit/ZUyJQInnygirvfohIhQo

1) $scope.gridOptions=finalObj; needs to be changed to $scope.gridOptions.data=finalObj;
2) $scope.gridOptions.data needs an array.
Try this:
function merge(obj1, obj2){
return obj1.map(function(o1){
return Object.assign({}, o1, {
col4: obj2.find(function(o2){ return o1.col1 == o2.col1 }).col2,
col5: obj2.find(function(o2){ return o1.col1 == o2.col1 }).col3
})
})
}
var finalObj = merge(one, two);
$scope.gridOptions.data=finalObj;
Plunker

Related

ReactJS and Material UI TreeView: Can I use a multi-level JSON/array of objects with different names to populate the TreeView?

I have an array of objects that is multi-leveled with different names that I need to populate a TreeView component :
export const application_group_one = [
{
id: uniqueId(),
name: "Application 1",
organizations: [
{
id: uniqueId(),
name: "Organization 1",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
],
},
],
},
{
id: uniqueId(),
name: "Application 2",
organizations: [
{
id: uniqueId(),
name: "Organization 1",
artifacts: [],
},
],
},
];
export const application_group_two = [
{
id: uniqueId(),
name: "Application 3",
organizations: [
{
id: uniqueId(),
name: "Organization 1",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifact 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
{
id: uniqueId(),
name: "Organization 2",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifact 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
{
id: uniqueId(),
name: "Organization 3",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifacy 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
{
id: uniqueId(),
name: "Organization 4",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifact 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
],
},
];
I'm able to output the Organizations but not the artifacts. Having varying names for each children object is giving me a hard time. I would like a TreeView that can expand as many levels as I want with differing names for the nest objects. :
const getTreeItemsFromData = (treeItems) => {
return treeItems.map((treeItemData) => {
let organizations = undefined;
if (treeItemData.organizations && treeItemData.organizations.length > 0) {
organizations = getTreeItemsFromData(treeItemData.organizations);
}
return <TreeItem key={treeItemData.id} nodeId={treeItemData.id} label={treeItemData.name} children={organizations} />;
});
};
const DataTreeView = ({ treeItems }) => {
return (
<TreeView defaultCollapseIcon={<ExpandMoreIcon />} defaultExpandIcon={<ChevronRightIcon />}>
{getTreeItemsFromData(treeItems)}
</TreeView>
);
};
export const Tree = () => {
return (
<div className="App">
<DataTreeView treeItems={application_group_one} />
<br />
<DataTreeView treeItems={application_group_two} />
</div>
);
};

Unique Array by comparing elements of array React JS

I have this array
array = [
{id: "one", title: "new 1"},
{id: "two", parent_id: "132132", title: "new 2"},
{id: "three", parent_id: "132132", title: "new 3"},
{id: "four", parent_id: "132132", title: "new 1"},
{id: "one", parent_id: "132132", title: "new 1"}
]
We need
array = [
{id: "two", parent_id: "132132", title: "new 2"},
{id: "three", parent_id: "132132", title: "new 3"},
{id: "four", parent_id: "132132", title: "new 1"},
{id: "one", parent_id: "132132", title: "new 1"}
]
We need to compare elements to get unique array with different avoiding other elements
I have tried using this method
uniqueArray = (arr) => {
return arr.filter((e, i, arr) => arr.findIndex(e2 => Object.keys(e2).every(prop => e2[prop] === e[prop])) === i);
};
I prefer Array.reduce for this kind of things:
const filteredArr = arr.reduce((acc, current) => {
const exists = acc.find(item => item.id === current.id);
if (!exists) {
return acc.concat([current]);
} else {
return acc;
}
}, []);
If I understand you correctly, you want to return object without the property of parentId. If so you can use this.
array.filter(arr => arr.hasOwnProperty("parentId"))

How to add values in an array inside an array in AngularJS

I apologize if my title sounds so confusing, as I don't know how to exactly word it. Basically, this is what I'm trying to do.
For example, I have the following array:
var sourceArray = [
{ question: "Question 1", inputType: "radio", answer: "Answer 1", id: "1" },
{ question: "Question 1", inputType: "radio", answer: "Answer 2", id: "2" },
{ question: "Question 1", inputType: "radio", answer: "Answer 3", id: "3" },
{ question: "Question 2", inputType: "radio", answer: "Answer 1", id: "4" },
{ question: "Question 2", inputType: "radio", answer: "Answer 2", id: "5" },
{ question: "Question 2", inputType: "radio", answer: "Answer 3", id: "6" }
]
I want to restructure this so that it'll look like this:
var newArray = [
{
question: "Question 1", inputType: "radio",
choices: [{answer: "Answer 1", id: "1"},
{answer: "Answer 2", id: "2"},
{answer: "Answer 3", id: "3"}
]},
{
question: "Question 2", inputType: "radio",
choices: [{answer: "Answer 1", id: "4"},
{answer: "Answer 2", id: "5"},
{answer: "Answer 3", id: "6"}
]}
]
Answers are grouped by question, so if the next question in the sourceArray is the same with the current, it will push the answers into the choices array.
Is this possible in AngularJS using angular.forEach?
Any help will be appreciated.
Thank you as always for your responses.
Here you go. See the working example below:
// Add a hepler method in the Array to find the value
Array.prototype.find = function(key, value) {
var index = -1;
angular.forEach(this, function(item, i) {
if (item[key] === value) {
index = i;
}
});
return this[index];
};
var app = angular.module("sa", []);
app.controller("FooController", function($scope) {
$scope.sourceArray = [{
question: "Question 1",
inputType: "radio",
answer: "Answer 1",
id: "1"
}, {
question: "Question 1",
inputType: "radio",
answer: "Answer 2",
id: "2"
}, {
question: "Question 1",
inputType: "radio",
answer: "Answer 3",
id: "3"
}, {
question: "Question 2",
inputType: "radio",
answer: "Answer 1",
id: "4"
}, {
question: "Question 2",
inputType: "radio",
answer: "Answer 2",
id: "5"
}, {
question: "Question 2",
inputType: "radio",
answer: "Answer 3",
id: "6"
}];
$scope.newArray = [];
$scope.convert = function() {
// Iterate array
angular.forEach($scope.sourceArray, function(item) {
// Check if the question alrady exists
if (!$scope.newArray.find('question', item.question)) {
// If not, push the question to the array with empty choices
$scope.newArray.push({
question: item.question,
inputType: item.inputType,
choices: []
});
}
var newArrayItem = $scope.newArray.find('question', item.question);
// Push the choices
newArrayItem.choices.push({
answer: item.answer,
id: item.id
});
});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<div ng-app="sa" ng-controller="FooController">
Before:
<br>{{sourceArray | json}}
<br>
convert
<br>After:
<br>{{newArray | json}}
</div>
You can group together using a for loop,
Here is the code:
function transformArr(orig) {
var newArr = [],
answers = {},
newItem, i, j, cur;
for (i = 0, j = orig.length; i < j; i++) {
cur = orig[i];
if (!(cur.question in answers)) {
answers[cur.question] = {question: cur.question, answers: [],inputType : cur.inputType,id :cur.id};
newArr.push(answers[cur.question]);
}
answers[cur.question].answers.push(cur.answer);
}
return newArr;
}
Working App
You need to filter in the sourceArray, the two Questions List as below:
var question1 = $filter('filter')(sourceArray, {
question: 'Question 1'
});
var question2 = $filter('filter')(sourceArray, {
question: 'Question 2'
});
After that, you should create a new data of array as below:
$scope.questionData = [{
"question": "Question 1",
"inputType": "radio",
"choices": []
}, {
"question": "Question 2",
"inputType": "radio",
"choices": []
}];
Then, you should run loops over the two filtered a variables into the new Array of object:
1):
angular.forEach(question1, function(value, key) {
if (value.question == $scope.questionData[0].question) {
$scope.questionData[0].choices.push({
'answer': value.answer,
'id': value.id
});
}
});
2):
angular.forEach(question2, function(value, key) {
if (value.question == $scope.questionData[1].question) {
$scope.questionData[1].choices.push({
'answer': value.answer,
'id': value.id
});
}
});
Refer here for demo:

Adding key value pair to specific objects in an array

I have an array of objects that looks like this:
[{headerName: "Test 1", field: "Test 1", type_id: 1}, {headerName: "Test 2", field: "Test 2", type_id: 2}, {headerName: "Test 3", field: "Test 3", type_id: 3}, {headerName: "Name", field: "Name", type_id: 3}, {headerName: "Income", field: "Income", type_id: 2}]
This is just a basic example of what the array might look like as it can be of any length. Basically what I need to do is when the type_id is 3 I need to add an extra key/value pair to those objects in the array.
How would I go about doing this?
Any help would be much appreciated.
Thanks for your time.
UPDATE:
Key/value pair I am trying to add is : cellRenderer: customEditor
An es6 solution
yourArray = yourArray.map( obj => {
if( obj.type_id === 3 ){
return { ...obj, cellRenderer: customEditor };
}
return obj;
}
An es5 solution
yourArray = yourArray.map( function( obj ){
if( obj.type_id === 3 ){
Object.defineProperty(obj, "cellRenderer", { value : customEditor })
}
return obj;
}
The solution using Array.map and Object.keys functions:
var arr = [{headerName: "Test 1", field: "Test 1", type_id: 1}, {headerName: "Test 2", field: "Test 2", type_id: 2}, {headerName: "Test 3", field: "Test 3", type_id: 3}, {headerName: "Name", field: "Name", type_id: 3}, {headerName: "Income", field: "Income", type_id: 2}],
extraObj = {'cellRenderer': 'customEditor'};
arr.map(function(obj){
if (obj['type_id'] === 3) {
Object.keys(this).forEach((k) => obj[k] = this[k]);
}
}, extraObj);
console.log(JSON.stringify(arr, 0, 4));
The output:
[
{
"headerName": "Test 1",
"field": "Test 1",
"type_id": 1
},
{
"headerName": "Test 2",
"field": "Test 2",
"type_id": 2
},
{
"headerName": "Test 3",
"field": "Test 3",
"type_id": 3,
"cellRenderer": "customEditor"
},
{
"headerName": "Name",
"field": "Name",
"type_id": 3,
"cellRenderer": "customEditor"
},
{
"headerName": "Income",
"field": "Income",
"type_id": 2
}
]
Another take combining map and Object.assign
var data = [{headerName: "Test 1", field: "Test 1", type_id: 1}, {headerName: "Test 2", field: "Test 2", type_id: 2}, {headerName: "Test 3", field: "Test 3", type_id: 3}, {headerName: "Name", field: "Name", type_id: 3}, {headerName: "Income", field: "Income", type_id: 2}];
var extend = { cellRenderer: 'customEditor' }
data = data.map( item => {
if( item.type_id == 3 ){
return Object.assign( item, extend );
}
return item;
});

Angular orderBy is not responding

I have an array obj as following:
$scope.list = [
{
_id: "1111",
desc: "Desc 1",
image_url: "uploads/name-1.jpg",
name: "Name 1",
sequence: 0
},
{
_id: "1112",
desc: "Desc 2"
image_url: "uploads/name-2.jpg",
name: "Name 2",
sequence: 2
},
{
_id: "1113",
desc: "Desc 3",
image_url: "uploads/name-3.jpg",
name: "Name 3",
sequence: 3
},
{
_id: "1114",
desc: "Desc 4",
image_url: "uploads/name-4.jpg",
name: "Name 4",
sequence: 4
},
{
_id: "1115",
desc: "Desc 5",
image_url: "uploads/name-5.jpg",
name: "Name 5",
sequence: 0
},
{
_id: "1116",
desc: "Desc 6",
image_url: "uploads/name-6.jpg",
name: "Name 6",
sequence: 0
},
];
and HTML
<span data-ng-repeat="item in list | orderBy: 'sequence' ">{{item.sequence}}</span>
I've also tried orderBy: '-sequence', orderBy: 'sequence':true. orderBy: 'sequence':false. But the order doesn't seem to update!
Can someone please shed some light on this?
Your list is badly defined, as you're missing commas.
The code you posted does work, see here.
<span ng-repeat="item in list | orderBy: 'sequence' ">
{{item.sequence}}
</span>

Resources