I want to create a treeview array for use in Angular UI Tree. I want to create the structure from a array of object like this:
0: Object
body: null
categoryDescription: null
categoryTopic: null
description: null
faqBodyId: 0
faqCategoryId: 0
faqGroupId: 1
groupDescription: null
groupName: "Generelt"
groupTopic: "Generelt"
themeCode: "GEN"
topic: null
1: Object body: null categoryDescription: "Test af kategori" categoryTopic: "Mail" description: null faqBodyId: 0 faqCategoryId: 2 faqGroupId: 1 groupDescription: null groupName: null groupTopic: null themeCode: null topic: null
2: Object body: "This is a test" categoryDescription: null categoryTopic: null description: "Testing" faqBodyId: 3 faqCategoryId: 2 faqGroupId: 0 groupDescription: null groupName: null groupTopic: null themeCode: null topic: "Test123"
etc...
It is in three levels. Group, Category and Body
A node does not allways have a child!
I want It in this structure and three levels:
[
{
"id": 1,
"title": "1. dragon-breath",
"items": []
},
{
"id": 2,
"title": "2. moiré-vision",
"items": [
{
"id": 21,
"title": "2.1. tofu-animation",
"items": [
{
"id": 211,
"title": "2.1.1. spooky-giraffe",
"items": []
},
{
"id": 212,
"title": "2.1.2. bubble-burst",
"items": []
}
]
},
{
"id": 22,
"title": "2.2. barehand-atomsplitting",
"items": []
}
]
},
{
"id": 3,
"title": "3. unicorn-zapper",
"items": []
},
{
"id": 4,
"title": "4. romantic-transclusion",
"items": []
}
]
Structure
How is that done with Angular code?
I solved the problem like this.
The input array is sorted:
function buildtree(arr) {
var group = [];
angular.forEach(arr, function (value, index) {
if (value.faqGroupId > 0 && value.faqCategoryId == 0 && value.faqBodyId == 0) {
var category = [];
var faqgroup = {
"id": value.faqGroupId,
"title": value.groupTopic,
"description": value.groupDescription,
"name": value.groupName,
"items": category
}
angular.forEach(arr, function (valuecat, index) {
if (value.faqGroupId == valuecat.faqGroupId && valuecat.faqCategoryId > 0 && valuecat.faqBodyId == 0) {
var body = [];
var faqcat = {
"id": valuecat.faqCategoryId,
"title": valuecat.categoryTopic,
"description": valuecat.categoryDescription,
"items": body
}
angular.forEach(arr, function (valuebod, index) {
if (valuecat.faqGroupId == valuebod.faqGroupId && valuecat.faqCategoryId == valuebod.faqCategoryId && valuebod.faqBodyId > 0) {
var faqbody = {
"id": valuebod.faqBodyId,
"title": valuebod.topic,
"description": valuebod.description,
"body": valuebod.body,
}
body.push(faqbody);
}
})
category.push(faqcat);
}
})
group.push(faqgroup);
}
});
return group;
}
Array list :
Flat object array list
var dataList= [
{'id':1 ,'parentid' : 0, 'label'="label 1"},
{'id':4 ,'parentid' : 2 ,'label'="label 2"},
{'id':3 ,'parentid' : 1, 'label'="label 3"},
{'id':5 ,'parentid' : 0, 'label'="label 4"},
{'id':6 ,'parentid' : 0, 'label'="label 5"},
{'id':2 ,'parentid' : 1, 'label'="label 6"},
{'id':7 ,'parentid' : 4, 'label'="label 7"},
{'id':8 ,'parentid' : 1, 'label'="label 8"}
];
covert flat object array list to treeview list
function flatListToTreeViewData(dataList) {
var tree = [],
mappedArr = {},
arrElem,
mappedElem;
for (var i = 0, len = dataList.length; i < len; i++) {
arrElem = dataList[i];
mappedArr[arrElem.id] = arrElem;
mappedArr[arrElem.id]['children'] = [];
}
for (var id in mappedArr) {
if (mappedArr.hasOwnProperty(id)) {
mappedElem = mappedArr[id];
array of children.
if (mappedElem.parentID) {
mappedArr[mappedElem['parentID']]['children'].push(mappedElem);
}else {
tree.push(mappedElem);
}
}
}
return tree;
}
Related
sample json data is this:
{
"variations": [
{
"variation_id": 391,
"name": "Fruit Shake - Chocolate, S",
"price": 10,
"attribute": [
{
"attribute_key": "pa_flavor",
"name": "Flavor",
"option": "Chocolate"
},
{
"attribute_key": "pa_size",
"name": "Size",
"option": "S"
}
]
},
{
"variation_id": 385,
"name": "Fruit Shake - Banana, L",
"price": 18,
"attribute": [
{
"attribute_key": "pa_flavor",
"name": "Flavor",
"option": "Banana"
},
{
"attribute_key": "pa_size",
"name": "Size",
"option": "L"
}
]
},
{
"variation_id": 386,
"name": "Fruit Shake - Banana, M",
"price": 15,
"attribute": [
{
"attribute_key": "pa_flavor",
"name": "Flavor",
"option": "Banana"
},
{
"attribute_key": "pa_size",
"name": "Size",
"option": "M"
}
]
}
]
}
my problem is, getting the variation_id where 2 or more attributes matches the array of string.
for example, chosenProduct = ["Banana", "L"]
I tried filter and contains but theres no way to match the other item from chosenProduct.
If I added the next condition, it returns nil
You can try this:
let varID = product.variations?.filter { att in
var matchedAttributes = 0
for thisAttribute in att.attribute {
if chosenProduct.contains(where: {$0 == thisAttribute.option}) {
matchedAttributes += 1
}
}
if matchedAttributes >= 2 {
return true
}
return false
}
Let me know if there's any doubt.
You can try this :
var chosenProduct = ["Banana","L"]
var expectedIds : [Int] = [Int]()
datas.variations?.map{ val in
val.attribute.map({ val2 in
let filtered = val2.enumerated().filter({chosenProduct.contains($0.element.option!)})
if filtered.count == chosenProduct.count{
expectedIds.append(val.variation_id!)
}
})
}
print(expectedIds) // [385]
I put the id's in array because of if you want to change your chosenProcudt example "Banana" (count 1 ). This mapping must be return variation_id like [385,386]
You can a method to Variation to make things easier:
extension Variation {
func attributesMatching(options: [String]) -> [Attribute] {
attribute.filter { options.contains($0.option) }
}
}
Then, you can just write:
let filtered = product.variations.filter { $0.attributesMatching(options: chosenProductOptions).count >= 2 }
print(filtered.map { $0.variationID })
I need your opinion in this situation:
I get from API with this function:
getRS(
idProject: string
): Observable<ResponseModel<RSModel>> {
return this.http.get<ResponseModel<RSModel>>(
ApiUrlsConfig.getRS(
idProject
)
);
}
this response:
{
"data": [
{
"id": "id1",
"state": 1,
"note": null
},
{
"id": "id1",
"state": 2,
"note": "Reason 1"
},
{
"id": "id2",
"state": 2,
"note": "Reason updated3",
}
],
"result": null
}
I need to use filter in this response because I should be get the last state for each id. For example, I want to display state 2 in item with id: id1. For this I want to use filter. The problem is because I can't use filter on it, I don't understand why.
I tried to write this code:
#Input() set jobId(jobId: string) {
this.optionsService
.getRS(
this.idProject
)
.pipe()
.subscribe((res) => {
let resId = res.filter((aaa)=>{
if(aaa.id === jobId){
res.slice(-1)[0].id
}
}
)
});
}
Not function.
Please can you share with me any idea?
Thank you
Try this logic:
Loop backwards throw it.
Loop backwards over index to the start.
Splice duplicates.
let response = {
"data": [
{
"id": "id1",
"state": 1,
"note": null
},
{
"id": "id1",
"state": 2,
"note": "Reason 1"
},
{
"id": "id2",
"state": 2,
"note": "Reason updated3"
}
],
"result": null
}
let data = response.data;
for (let i = data.length - 1; i >= 0; i--) {
for (let j = i - 1; j >= 0; j--) {
if (data[i].id === data[j].id) {
data.splice(j, 1);
j++;
}
}
};
console.log(data);
try this:
if(aaa.id == jobId){
return res.slice(-1)[0].id
}
Suppose I have the following payload with nested array, how do I combine the array inside the nested array for the same externalId as well as some logic on certain field like
shipQty - this field will be sum or add up for records with the same externalId under fillingOrder
serialNumbers - all the records under serialNumbers will be display together if the externalId is same
Kindly refer below for the input and expected output
Json Payload Input
{
"Identifier": "9i098p-898j-67586k",
"transactionDate": "2019-09-08T10:01:00-04:00",
"order": [
{
"orderNumber": "123456789",
"CourierOrderId": "1300-88-2525",
"fillingOrder": [
{
"numberOfBoxes": 0,
"tracking": [
{
"carrier": "Orange",
"trackNum": "3333444",
"trackUrl": "https://www.orange.com/track/status",
"shipDate": "2019-09-08T10:01:00-04:00",
"SerialNumber": "00000123"
}
],
"row": [
{
"externalId": "1",
"unitNo": "OP04-123456-789",
"shipQty": 2,
"serialNumbers": [
{
"serialNumber": "USD333555",
"quantity": 1
},
{
"serialNumber": "USD235678",
"quantity": 1
}
]
}
]
},
{
"tracking": [
{
"carrier": "Apple",
"trackNum": "555666",
"trackUrl": "https://www.apple.com/track/status",
"shipDate": "2019-09-08T10:01:00-04:00",
"SerialNumber": "00000645"
}
],
"row": [
{
"externalId": "1",
"unitNo": "OP04-123456-789",
"shipQty": 3,
"serialNumbers": [
{
"serialNumber": "USD123456",
"quantity": 1
},
{
"serialNumber": "USD98765",
"quantity": 1
},
{
"serialNumber": "USD45689",
"quantity": 1
}
]
}
]
},
{
"tracking": [
{
"carrier": "banana",
"trackNum": "587390",
"trackUrl": "https://www.banana.com/track/status",
"shipDate": "2019-09-08T10:01:00-04:00",
"SerialNumber": "00000365"
}
],
"row": [
{
"externalId": "2",
"unitNo": "OP05-123456-111",
"shipQty": 2,
"serialNumbers": [
{
"serialNumber": "USD00045",
"quantity": 1
},
{
"serialNumber": "USD00046",
"quantity": 1
}
]
}
]
}
]
}
]
}
Expected Json Output
{
"row": [
{
"externalId": "1",
"unitNo": "OP04-123456-789",
"shipQty": 5, //the shipQty should be add up when the externalId is same
"serialNumbers": [ //the serialNumbers should display all the data inside the serialNumbers when the externalId is same
{
"serialNumber": "USD333555",
"quantity": 1
},
{
"serialNumber": "USD235678",
"quantity": 1
},
{
"serialNumber": "USD123456",
"quantity": 1
},
{
"serialNumber": "USD98765",
"quantity": 1
},
{
"serialNumber": "USD45689",
"quantity": 1
}
]
},
{
"externalId": "2",
"unitNo": "OP05-123456-111",
"shipQty": 2,
"serialNumbers": [
{
"serialNumber": "USD00045",
"quantity": 1
},
{
"serialNumber": "USD00046",
"quantity": 1
}
}
]
}
It looks like you only need the data of "row" inside the fillingOrder field of your payload. So first thing to simplicy the problem is to get all the rows as a single array. Once you have that them you just need to group that by external id and the problem will start to look smaller.
%dw 2.0
output application/json
//First get all rows since it looks like you only need them.
//If you find this confusing try to use flatten with some simpler payloads.
var allRows = flatten(flatten(payload.order.fillingOrder).row)
//Group them according to external id.
var groupedExtId = allRows groupBy $.externalId
---
{
row: groupedExtId pluck ((value, extId, index) -> do {
var sumShipQuant = sum(value.shipQty default [])
---
{
externalId: (extId), //the key after grouping is external id
unitNo: value.unitNo[0], //assuming it is same across diff external id
shipQty: sumShipQuant,
serialNumbers: flatten(value.serialNumbers) //Flatten because value is an array and it has multiple serielNumbers array
}
})
}
This should help. I took some inspiration from Harshank Bansal post
%dw 2.0
output application/json
var groupFlat = flatten(flatten (payload.order.fillingOrder).row) groupBy ($.externalId)
---
row: [groupFlat mapObject ((value, key, index) -> {
externalId: value.externalId[0],
unitNO: value.unitNo[0],
shipQty: sum(value.shipQty),
serialNumbers: flatten(value.serialNumbers)
})]
Try this:
%dw 2.0
output application/json
---
row:[ if (payload..order..row..externalId[0] == payload..order..row..externalId[1]) {
externalId : payload..order..row..externalId[0],
unitNo: payload..order..row..unitNo[0],
shipQty: payload..order..row..shipQty[0] + payload..order..row..shipQty[1],
serialNumbers: flatten (payload..order..row..serialNumbers)
}
else null]
I have a json file and I'm trying to remove an element with below code .
exports.delete = function(req, res) {
var deletearticle = articles[req.params.id];
delete articles[req.params.id];
fs.writeFile('server/articles.json',JSON.stringify(articles, null, 4),finished);
function finished(err){
console.log("--->After deletion, article list:\n" + JSON.stringify(articles, null, 4) );
}
res.end(JSON.stringify(deletearticle, null, 4));
};
after removing the element my json file will be like :
[
{
"header": "Jack",
"body": "Davis",
"date": "",
"id": 0
},
null,
{
"header": "dfd",
"body": "dgfgfgfgfdgfg",
"date": "2018-11-24T16:33:48.842Z",
"id": 2
}]
and I get error on client side :
{articles ? articles.map(({ id, header ,body}) => (
<div key={id} timeout={500} className="fade">
<div className="article">
<h2 className="article_title">{header}</h2>
Because one of my JSON's element is null it says that can't read id from null.Is There any better way to remove this element from my json file ? or i can check if srticle is not null in client side.
Just filter your object, Assume here a is your JSON array and you have to filter all object which does not have null
a = a.filter(function(obj){ if(obj != null) return obj })
Now print a, It will filter out all object except null objects
You can use array.splice to remove object from an array, as you have id of an object, you first need to find the index of an object to be removed and then you can remove it easily using splice.
For your reference avoid using delete
var sampleArray= [{
"header": "Jack",
"body": "Davis",
"date": "",
"id": 5
},
{
"header": "Jack",
"body": "Davis",
"date": "",
"id": 6
},
{
"header": "dfd",
"body": "dgfgfgfgfdgfg",
"date": "2018-11-24T16:33:48.842Z",
"id": 7
}
];
var id = 5;
var index = sampleArray.findIndex(a=> a.id === id);
if (index > -1) {
sampleArray.splice(index, 1);
}
console.log(sampleArray);
You can delete element without keeping null like this...
array.splice(index, 1);
Or,You can remove null elements by doing like this...
var array = [
{
"header": "Jack",
"body": "Davis",
"date": "",
"id": 0
},
null,
{
"header": "dfd",
"body": "dgfgfgfgfdgfg",
"date": "2018-11-24T16:33:48.842Z",
"id": 2
}];
// filter array
var filtered = array.filter(function (el) {
return el != null;
});
var a = [
{
"header": "Jack",
"body": "Davis",
"date": "",
"id": 0
},
null,
{
"header": "dfd",
"body": "dgfgfgfgfdgfg",
"date": "2018-11-24T16:33:48.842Z",
"id": 2
}];
//using es6 array.filter to filter null or undefined or empty object
var filtered = array.filter((x)=>{
for (var key in filter) {
if (x[key] === undefined || x[key] !== null || x[key]!=='')
return false;
}
return true;
});
Hi can somebody help Removing element from nested json array like this
JSON
[{
"id": 1,
"name": "Furniture & Fixture",
"choice": {
"0": {
"req_goods": "table",
"qty": "10"
},
"1": {
"req_goods": "chair",
"qty": "5"
}
}
}, {
"id": 2,
"name": "Miscellaneous Property",
"choice": {
"0": {
"req_goods": "Office Rent",
"qty": "1"
}
}
}]
here how do I remove choice 1 of id 1 .
HTML
<div ng-repeat="cb in capital_budgets">
<div ng-repeat="choice in choices[$index]">
<input ng-model="cb.choice[$index].req_goods">
<input ng-model="cb.choice[$index].qty">
<button ng-hide="$first" ng-click="removeChoice($parent.$index,$index)">-</button>
</div>
<button ng-click="addNewChoice($index)">+</button>
</div>
JS
$scope.capital_budgets = [{"id":1,"name":"Furniture & Fixture"},
{"id":2,"name":"Miscellaneous Property"}];
$scope.choices = [{}];
$scope.choices[0] = [{}];
$scope.choices[1] = [{}];
$scope.choices[2] = [{}];
$scope.choices[3] = [{}];
$scope.choices[4] = [{}];
$scope.addNewChoice = function(id) {
$scope.choices[id].push({});
};
$scope.removeChoice = function(parent_id, id) {
$scope.choices[parent_id].splice(id, 1);
};
The Above removeChoice() remove last element but I want to remove the element that user choose to remove. please help i have been trying from 2 days.
You can make 'choice' of the array type as follows and use the index of the particular choice in the ng-repeat directive to remove the choice from the choices array.
angular
.module('demo', [])
.controller('DefaultController', DefaultController);
function DefaultController() {
var vm = this;
vm.items = [
{
"id": 1,
"name": "Furniture & Fixture",
"choices": [
{
"id": 1,
"req_goods": "table",
"qty": "10"
},
{
"id": 2,
"req_goods": "chair",
"qty": "5"
}]
}, {
"id": 2,
"name": "Miscellaneous Property",
"choices": [
{
"id": 1,
"req_goods": "Office Rent",
"qty": "1"
}]
}];
vm.removeChoice = removeChoice;
vm.addChoice = addChoice;
function removeChoice(itemId, index) {
for (var i = 0; i < vm.items.length; i++) {
if (vm.items[i].id === itemId) {
vm.items[i].choices.splice(index, 1);
break;
}
}
}
function addChoice(index) {
var id = vm.items[index].choices.length + 1;
vm.items[index].choices.push({
id: id,
req_goods: "",
qty: 0
});
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo">
<div ng-controller="DefaultController as ctrl">
<div ng-repeat="item in ctrl.items">
<h3>{{item.name}}</h3>
<div ng-repeat="choice in item.choices">
<input type="text" ng-model="choice.req_goods" />
<input type="text" ng-model="choice.qty" />
<button type="button" ng-click="ctrl.removeChoice(item.id, $index)">Remove</button>
</div>
<button type="button" ng-click="ctrl.addChoice($index)">Add</button>
</div>
</div>
</div>
You can remove choice "1" of id 1 using the below code snippet.
var json = [
{
"id": 1,
"name": "Furniture & Fixture",
"choice": {
"0": {
"req_goods": "table",
"qty": "10"
},
"1": {
"req_goods": "chair",
"qty": "5"
}
}
}, {
"id": 2,
"name": "Miscellaneous Property",
"choice": {
"0": {
"req_goods": "Office Rent",
"qty": "1"
}
}
}];
function removeChoice(json, parentId, choice) {
for (var i = 0; i < json.length; i++) {
if (json[i].id === parentId) {
delete json[i].choice[choice];
break;
}
}
}
removeChoice(json, 1, "1");
console.log(json);
If you want the the choice also to be of the same type as its parent element i.e. an array you could change your JSON as follows and do as shown in the below code snippet to remove a choice from the JSON
var json = [
{
"id": 1,
"name": "Furniture & Fixture",
"choices": [
{
"id": 1,
"req_goods": "table",
"qty": "10"
},
{
"id": 2,
"req_goods": "chair",
"qty": "5"
}]
}, {
"id": 2,
"name": "Miscellaneous Property",
"choices": [
{
"id": 1,
"req_goods": "Office Rent",
"qty": "1"
}]
}];
function removeChoice(json, parentId, choiceId) {
for (var i = 0; i < json.length; i++) {
if (json[i].id === parentId) {
for (var j = 0; j < json[i].choices.length; j++) {
if (json[i].choices[j].id === choiceId) {
json[i].choices.splice(j, 1);
break;
}
}
break;
}
}
}
removeChoice(json, 1, 1);
console.log(json);
In both of the above methods I've passed the source you want to modify as a parameter to the removeChoice function whereas you can also directly use a variable available within the scope of execution of the removeChoice function and pass only parentId and choiceId as parameters in the below code snippet, you can replace items with the object on your controller's $scope.If you prefer isolation of the code you can pass the items object as a parameter to the removeChoice function as it won't be dependent on the external components directly being used in the method body, I would suggest to have separation of concerns.
var items = [
{
"id": 1,
"name": "Furniture & Fixture",
"choices": [
{
"id": 1,
"req_goods": "table",
"qty": "10"
},
{
"id": 2,
"req_goods": "chair",
"qty": "5"
}]
}, {
"id": 2,
"name": "Miscellaneous Property",
"choices": [
{
"id": 1,
"req_goods": "Office Rent",
"qty": "1"
}]
}];
function removeChoice(parentId, choiceId) {
for (var i = 0; i < items.length; i++) {
if (items[i].id === parentId) {
for (var j = 0; j < items[i].choices.length; j++) {
if (items[i].choices[j].id === choiceId) {
items[i].choices.splice(j, 1);
break;
}
}
break;
}
}
}
removeChoice(1, 1);
console.log(items);
Try This
$scope.removeChoice = function(parent_id,id) {
var TempArr=[];
var parentLength=$scope.choices[parent_id].length;
for(i=0;i<parentLength;i++ ){
if(parentLength[i]!==id){
TempArr.push(parentLength[i]);
}
if(i==parentLength-1){
$scope.choices[parent_id]=[];
$scope.choices[parent_id]=TempArr;
}
}
};