LogicApp/JavaScript - Split JSON data to multiple objects and arrays - javascript

I have below JSON data coming from source system into my Logic App:
[
{
"project":"abc",
"assignees":"123,456"
},
{
"project":"xyz",
"assignees":"123,468"
}
]
I want to split the "assignees", create arrays within objects, and produce below final output:
[
{
"metadata":{
"type":"project"
},
"name":"Project ABC",
"assignee":[
{
"metadata":{
"type":"assignment"
},
"employeeId":"123"
},
{
"metadata":{
"type":"assignment"
},
"employeeId":"123"
}
]
},
{
"metadata":{
"type":"project"
},
"name":"Project ABC",
"assignee":[
{
"metadata":{
"type":"assignment"
},
"employeeId":"123"
},
{
"metadata":{
"type":"assignment"
},
"employeeId":"468"
}
]
}
]
Can this be achieved in Logic App only? If not, can this be achieved using inline JavaScript code and how?

I don't know anything about LogicApp or how it works, but if all you want is javascript code that can make this transformation you can do something like this:
const src=[
{
"project":"abc",
"assignees":"123,456"
},
{
"project":"xyz",
"assignees":"123,468"
}
]
const transformed=src.map(entry=>({
"metadata":{type:"project"},
name:"Project "+entry.project.toUpperCase(),
assignee:entry.assignees.split(",").map(assignee=>({
metadata:{type:"assignment"},
emplyeeId:assignee
}))
}))

I initialize a variable named source to store same data source with yours.
And here provide a sample of inline javascript code for your reference:
var source = workflowContext.actions.Initialize_variable.inputs.variables[0].value;
var result = [];
source.forEach(sItem=>{
var resultItem = {
"metadata":{
"type":"project"
},
"name":"Project " + sItem.project.toUpperCase()
}
var assignee = [];
var assigneesSplit = sItem.assignees.split(",");
assigneesSplit.forEach(item=>{
var assigneItem = {
"metadata":{
"type":"assignment"
},
"employeeId":item
}
assignee.push(assigneItem);
});
resultItem.assignee = assignee;
result.push(resultItem);
});
return result;
After running the logic app, we can get the result data like:
[
{
"metadata": {
"type": "project"
},
"name": "Project ABC",
"assignee": [
{
"metadata": {
"type": "assignment"
},
"employeeId": "123"
},
{
"metadata": {
"type": "assignment"
},
"employeeId": "456"
}
]
},
{
"metadata": {
"type": "project"
},
"name": "Project XYZ",
"assignee": [
{
"metadata": {
"type": "assignment"
},
"employeeId": "123"
},
{
"metadata": {
"type": "assignment"
},
"employeeId": "468"
}
]
}
]
It seems there are some mistakes in your expected data sample(such as the second project name and the second employeeId in first assignee field). If they are not typo, please let me know, I will modify my js inline code to implement your expected json data.

Related

How to retrieve and process the data from the open dialog form?

I'm trying to process the response data in the open dialog but got stuck in this the retrieval.
I followed the step by step procedure given in this link: https://developers.google.com/chat/how-tos/dialogs but unfortunately, it didn't work as well.
Here is the sample code:
My goal is to get the data from the dialog form then process it. My pain point is in the code: event.common.formInputs.firstnumber.stringInputs.value[0] where it returns undefined reading value.
function openDialog(event) {
return {
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Addition Calculator:",
"widgets": [
{
"textInput": {
"label": "First Number",
"type": "SINGLE_LINE",
"name": "firstnumber"
}
},
{
"textInput": {
"label": "Second Number",
"type": "SINGLE_LINE",
"name": "secondnumber"
}
},
{
"textInput": {
"label": "Third Number",
"type": "SINGLE_LINE",
"name": "thirdnumber"
}
},
{
"buttonList": {
"buttons": [
{
"text": "Submit",
"onClick": {
"action": {
"function": "giveAnswer"
}
}
}
]
},
"horizontalAlignment": "END"
}
]
}
]
}
}
}
}
};
}
function giveAnswer(event) {
var firstterm = parseFloat(event.common.formInputs.firstnumber.stringInputs.value[0])
var secondterm = parseFloat(event.common.formInputs.secondnumber.stringInputs.value[0])
var thirdterm = parseFloat(event.common.formInputs.thirdnumber.stringInputs.value[0])
var sum = firstterm+secondterm+thirdterm
return {
"cardsV2": [{
"cardId": "addContact",
"card": {
"header": {
"title": "The SUM is:",
"subtitle": "Answer",
"imageUrl": "https://images.emojiterra.com/google/noto-emoji/v2.034/128px/1f4f1.png",
"imageType": "SQUARE"
},
"sections": [
{
"widgets": [
{
"textParagraph": {
"text": sum
}
}
]
}
]
}
}
]
}
}
I tried the example in here but didn't work as well. https://developers.google.com/chat/how-tos/dialogs#receive_form_data_from_dialogs

How to find the value nested inside an array of objects

Here I have to get value of file_info, I tried doing it using array.includes and array.find(), but got undefined.
My confusion here is related to, under 'facts', the first value is "==", then it has array of values associated to it. I could not figure out to find the values inside that nested object.
I even tried array.find(facts).contains(fileinfo) that did not work as well.
How can I solve this ??
"data": [
{
"task-id": "126e7267",
"type": "A",
"output": {...}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
},
....
]
}
},
{
"task-id": "5f557eac",
"type": "C",
....
},
],
I have tried to validate your json string. It seems to be invalid. For answering this question , i would assume below string to be your json :
{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}
I had tried to figure out a repetative pattern in your json but since "#value" tag is seen inside only one "facts" object below code should help you getting started . For given json , below code prints the value of "file_info"(Here , i'am assuming that "file_info" should be followed by a colon(:) i.e. "a0s5b2e6e739" is the value you are looking for) :
var jsonStr = '{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}';
var jsonObj = JSON.parse(jsonStr);
//If there is a repetative pattern , you can replace this hard coding with your pattern.
var objArray = jsonObj["data"][1]["output"]["facts"][0]["=="][1]["#value"]["facts"];
console.log(objArray);
if(objArray && objArray.length >0){
for(let i =0;i<objArray.length;i++){
if(objArray[i] && objArray[i]["=="] && objArray[i]["=="].length > 0 && objArray[i]["=="][0]["file_info"]){
//here "file_info" is fetched
console.log('here ',objArray[i]["=="][0]["file_info"]);
}
}
}
Hope above code helps you to get started.
You can map and filter the object/array to get the result if the format is fixed. Here, I am writing to a Map and retrieving the property I need at the very end.
let data = [
{
"task-id": "126e7267",
"type": "A",
"output": {}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
}
]
}
},
{
"task-id": "5f557eac",
"type": "C",
"output": {}
}
]
const map = new Map()
const facts = data
.map(d => d.output)
.filter(o => o.hasOwnProperty('facts'))
.map(d => d.facts)
.map(i => i[0]["=="][1])
.map(d => d["#value"].facts)
const item = facts.forEach(o => o.forEach(i => map.set(i["=="][0], i["=="][1])))
console.log(map.get("file_info"))

how to return an array inside an array javascript

i have an array inside an array...how do i return all the values using a for loop in javascript/angular?
for example my json...
[
{
"Name": "element1",
"Attributes": [
{"file":"document.doc"},
{"file":"document2.doc"}
]
},
{
"Name": "element2",
"Attributes": [
{"file":"document3.doc"},
{"file":"document4.doc"}
]
},
{
"Name": "element3",
"Attributes": [
{"file":"document5.doc"},
{"file":"document6.doc"}
]
}
]
having a tough time just returning all the files within attributes...only seem to be getting the first one everytime.
EDIT:
what i have so far..
function getAllFiles() {
for (var i = 0; i < Attributes.file.length; i++) {
return Attributes.file[i];
}
}
One of the methods how to get the desired output, using Array#reduce.
var json = [{Name:"element1",Attributes:[{file:"document.doc"},{file:"document2.doc"}]},{Name:"element2",Attributes:[{file:"document3.doc"},{file:"document4.doc"}]},{Name:"element3",Attributes:[{file:"document5.doc"},{file:"document6.doc"}]}],
res = json.reduce(function(s,a){
s.push(...a.Attributes.map(c => c.file));
return s;
}, []);
console.log(res);
ES5
var json = [{Name:"element1",Attributes:[{file:"document.doc"},{file:"document2.doc"}]},{Name:"element2",Attributes:[{file:"document3.doc"},{file:"document4.doc"}]},{Name:"element3",Attributes:[{file:"document5.doc"},{file:"document6.doc"}]}],
res = json.reduce(function(s,a){
s = s.concat(a.Attributes.map(c => c.file));
return s;
}, []);
console.log(res);
try
var files = [];
json.forEach(function(obj) {
obj.Attributes.forEach(function (f) {
files.push(f.file); })
});
this loops on the json array then on each element's attributes then adds the vilue of file
You could show all the files using Array methods like map and reduce:
var data = [{
"Name": "element1",
"Attributes": [{
"file": "document.doc"
},
{
"file": "document2.doc"
}
]
},
{
"Name": "element2",
"Attributes": [{
"file": "document3.doc"
},
{
"file": "document4.doc"
}
]
},
{
"Name": "element3",
"Attributes": [{
"file": "document5.doc"
},
{
"file": "document6.doc"
}
]
}
];
var files = data.map(function (obj) {
return obj.Attributes.map(function (i) {
return i.file;
});
}).reduce(function (x, y) {
return x.concat(y);
});
console.log(files);
Although Kind user's answer is better:
var data = [{
"Name": "element1",
"Attributes": [{
"file": "document.doc"
},
{
"file": "document2.doc"
}
]
},
{
"Name": "element2",
"Attributes": [{
"file": "document3.doc"
},
{
"file": "document4.doc"
}
]
},
{
"Name": "element3",
"Attributes": [{
"file": "document5.doc"
},
{
"file": "document6.doc"
}
]
}
];
var files = data.reduce(function(acc, val) {
return acc.concat(
val.Attributes.map(function(attribute) {
return attribute.file;
})
);
}, []);
console.log(files);
I renamed some variables so that the code makes more sense (to me).
Something like outerArray.innerArray. in your case arrayName.Attributes should work.

Merge and match objects that match AngularJS

Hello I would like to merge and match two json objects. I would like to do with the Angular way. Any help would be greatly appreciated. Thank you everyone. Here is an example:
// First json object
{
"UserID":"john.davis",
"edpi":null,
"UserApp":[
{
"Name":"name3",
"Link":"/Protect3.php"
},
{
"Name":"name5",
"Link":"/Admin/Launch.html"
},
{
"Name":"name2",
"Link":"aaap/defaultBH.php"
}
]
}
// Second json object
[
{
"color":"color1",
"icon": "content/images/icons/administrator.svg",
"Name": "name5"
},
{
"color":"color3",
"icon": "content/images/icons/administrator.svg",
"Name": "name3"
},
{
"color":"color2",
"icon": "content/images/icons/behavior.svg",
"Name": "name2"
}
]
Hoping to get this
[
{
"TokenName":"name3",
"TokenLink":"../Protect3.asp",
"color":{
"color":"color3",
"icon": "content/images/icons/administrator.svg",
"match": "name3"
}
},
{
"Name":"name5",
"Link":"/Admin/Launch.html",
"color":{
"color":"color1",
"icon": "content/images/icons/administrator.svg",
"match": "name5"
}
},
{
"Name":"name2",
"Link":"aaap/defaultBH.php"
"color":{
"color":"color2",
"icon": "content/images/icons/behavior.svg",
"match": "name2"
}
}
]
I figured it out. Here is the code below.
function mergeArraysOnProperty(array1, array2, property) {
array1.forEach(function(element1) {
array2.forEach(function(element2) {
if (element1[property] === element2[property]) {
for (var newProperty in element2) {
if (element2.hasOwnProperty(newProperty)) {
element1[newProperty] = element2[newProperty];
}
}
}
});
});
return array1;
};
$scope.newjson = mergeArraysOnProperty(userapp, color, "Name");
console.log($scope.newjson);

Filtering subarray of objects

I need to filter a subarray of elements.
var university = {
"fax": "123345",
"email": "test#test.com",
"url": "www.test.com",
"classes": [
{
"number": "1",
"name": "maths",
"students": [
{
"name": "Max",
"exams": [
{
"date": "2016-01-04T18:32:43.000Z",
"passed": false
},
{
"date": "2016-01-04T18:32:43.000Z",
"passed": true
},
{
"date": "2016-01-04T18:32:43.000Z",
"passed": false
},
{
"date": "2016-01-04T18:32:43.000Z",
"passed": true
}
]
},
{...}
]
},
{...}
]
}
Ok I need to get all the classes without filtering, all the students of each class without filtering, but in the exams array I only need to get the ones that passed.
I tried the following:
university.classes.students.exams.filter(function (el) {
return el.passed
});
But it is not working...
I've googled a solution to this without success...any help would be appreciated.
classes and students are arrays - so you have to loop those as well:
university.classes.forEach(function(uniClass) {
uniClass.students.forEach(function(student) {
student.exams = student.exams.filter(function (el) {
return el.passed;
});
});
});

Categories