Parse Dynamic Multiple Choice into JSON object
I have a DMC field that takes these values (dynamic value):
let all_entities := (select elements);
let my_event := this;
let my_elements := ((select elements where 'parent entry'.'testifies to events'.'testifies to event' like my_event) order by 'parent entry'.Id);
my_elements
The DMC shows (dynamic value name):
'has label'.label + ": " + text + " (entry: " + 'parent entry'.ID_entry + ")"
I'd want to have a JSON object that parses over all selected values
E.g.
[
{
"entry": ID_entry,
"elements": [
{
"text": text,
"label": label
},
{
"text": text,
"label": label
}
]
}
]
Mind that there can be multiple entries (ID_entry).
Currently, I only manage to parse this as a string and very awkwardly:
let myMi := numbers(Elements);
let myT := "";
let tmp_item := "";
for i in myMi do
let tmp_item := (select elements where number(Id) = i);
myT := myT + "," + """entry""" + ":" +
tmp_item.'parent entry'.'testifies to events'.'testifies to event' +
"," +
"""" +
"elements" +
"""" +
": [{" +
first("""text""" + ":" + """" + tmp_item.text + """, ""label""" + ":" + """" +
tmp_item.'has label'.label +
"""") +
"}]"
end;
myT := substr(myT, 1);
myT := "[{" + myT + "}]";
myT
A (externally formatted) example result is
[{
"entry": 134,
"elements": [{
"text": "Per Obitum List",
"label": "EVENT"
}
],
"entry": 134,
"elements": [{
"text": "Romae",
"label": "LOCATION"
}
],
"entry": 134,
"elements": [{
"text": "Dominicus Marques",
"label": "SUCCESSOR"
}
]
}
]
17 replies
-
I have tried, e.g., also
let myMi := numbers(Elements); let entries := []; for i in myMi do let tmp_items := (select elements where number(Id) = i); if count(tmp_items) > 0 then let entryId := first(tmp_items).'parent entry'.'testifies to events'.'testifies to event'; let elementsArray := []; for tmp_item in tmp_items do let element := { text: tmp_item.text, label: tmp_item.'has label'.label }; elementsArray := elementsArray + element; end; let entry := { entry: entryId, elements: elementsArray }; entries := entries + entry; end; end; formatJSON(entries)
-
Thankfully Ninox has an easier way of creating JSONs. This method is very handy for dynamic printing and creating new DB within a your DB so you can create HTML tables.
To start all you need is an array of nid or rid. So in your case you can start with:
let myMi := for loop1 in numbers(Elements) do record(elements,loop1) end;
Then you can just to the following to create a json:
myMi.{ entry: ID_entry, 2ndjsonname: fieldname2fromtable, }
You will see that Ninox will create a json for each record you select in your dMC.
Now how do you add in a Many reference table?
myMi.{ entry: ID_entry, 2ndjsonname: fieldname2fromtable, jsonName4referencetable: for loop2 in referencefieldname do { 3rdjsonname: loop2.fieldname1, 4thjsonname: loop2.fieldname3, } end }
So in the end you should see something like:
let myMi := for loop1 in numbers(Elements) do record(elements,loop1) end; myMi.{ entry: ID_entry, 2ndjsonname: fieldname2fromtable, jsonName4referencetable: for loop2 in referencefieldname do { 3rdjsonname: loop2.fieldname1, 4thjsonname: loop2.fieldname3, } end }
Here is an example from my DB:
let getRecs := for loop1 in numbers('Pre-Production Runs') do record(Production,loop1) end; getRecs.{ recID: Id, Arts: Article; for loop2 in Article.'Article Line' do { artID: Article, matID: loop2.Materials } end }
And this is the results:
[{"recID":"B19","Arts":[{"artID":1,"matID":2},{"artID":1,"matID":5}]},{"recID":"B20","Arts":[{"artID":1,"matID":2},{"artID":1,"matID":5}]}]
-
Thank you so much. This is certainly the way to go, yet, I don't manage to get what I need.
I think it has to do with the DMC. It's on a table 'events' and lists 'elements' that are linked to 'entries' via 'parent entry'.so, the second loop in you example is relative to 'elements' but actually I would need to start from 'entries' so that the elements are grouped by entry.
This code, e.g. does in a much better way something similar to my initial approach:
let myMi := for loop1 in numbers(Elements) do record(elements,loop1) end; myMi.{ entry: 'parent entry', elements: { text: text, label: 'has label'.label } }
Result:
[{"entry":1212,"elements":{"text":"Sancti Stephani de oculo","label":"PLACE"}},{"entry":1212,"elements":{"text":"24 cum incertis 40 D","label":"FINANCIAL"}},{"entry":1213,"elements":{"text":"Romae","label":"LOCATION"}},{"entry":1213,"elements":{"text":"Oxonen","label":"DIOCESE"}},{"entry":1213,"elements":{"text":"Joannes albarez","label":"SUCCESSOR"}}]
Any idea how I can put this upside down?
entry, elements: [{label, text},{label, text}],...
-
let myMi := for loop1 in numbers(Elements) do record(entries,loop1) end; myMi.{ entry: trancription }
No code error but [] result.
-
said:
Any idea how I can put this upside down?
entry, elements: [{label, text},{label, text}],...you just swap label and text.
myMi.{ entry: 'parent entry', elements: { label: 'has label'.label, text: text, } }
-
said:
The swap of text and label was not the issue but the elements get grouped by entry instead of the other way around (as currently).Everything is grouped by record in elements, as that is what myMi is based on.
You might need create another variable before you start building JSON.
Looks like you want create a JSON based on each instance of entry from a selection that is based on records in elements.
'parent entry'.'testifies to'.event.'is testified by'.entry
So you could try:
let myMi := for loop1 in numbers(Elements) do record(elements,loop1) end; let myMientries := unique(myMi.'parent entry'.'testifies to'.event.'is testified by'.entry); myMientries.{ entry: Id, }
It looks like entry is a reference field as well so you are now starting from that table and all references to fields start from there.
If I'm way off, maybe you can post a sample (no personal data) DB and I can get a better understanding of what is going on.
-
Yes, this did the trick! Wonderful.
let myMi := for loop1 in numbers(Elements) do record(elements,loop1) end; let myMientries := unique(myMi.'parent entry'); myMientries.{ entry: number(ID), elements: for loop2 in myMi do { Id: loop2.number(Id), text: loop2.text, label: loop2.'has label'.label } end }
will lead to
[{ "entry": 1212, "elements": [{ "Id": 15620, "text": "Sancti Stephani de oculo", "label": "PLACE" }, { "Id": 15624, "text": "24 cum incertis 40 D", "label": "FINANCIAL" }, { "Id": 15626, "text": "Romae", "label": "LOCATION" }, { "Id": 15627, "text": "Oxonen", "label": "DIOCESE" }, { "Id": 15628, "text": "Joannes albarez", "label": "SUCCESSOR" } ] }, { "entry": 1213, "elements": [{ "Id": 15620, "text": "Sancti Stephani de oculo", "label": "PLACE" }, { "Id": 15624, "text": "24 cum incertis 40 D", "label": "FINANCIAL" }, { "Id": 15626, "text": "Romae", "label": "LOCATION" }, { "Id": 15627, "text": "Oxonen", "label": "DIOCESE" }, { "Id": 15628, "text": "Joannes albarez", "label": "SUCCESSOR" } ] } ]
-
Ah, not quite!
The issue is that entry 1212 has two elements and 1213 three. So, these are not assigned based on the 'parent entry' but are all repeated for both entries.
-
Maybe that helps, take a look at the dMC directly that digest the relevant information
-
I guess this is it:
let myMi := for loop1 in numbers(Elements) do record(elements,loop1) end; let myMientries := unique(myMi.'parent entry'); myMientries.{ entry: number(ID), elements: for loop2 in myMi do if loop2.'parent entry' = ID then { Id: loop2.number(Id), text: loop2.text, label: loop2.'has label'.label } end end }
Content aside
- Status Answered
- 11 mths agoLast active
- 17Replies
- 159Views
-
4
Following