I am looking to access nested JSON data from a firebase database to use within a listView
, this is something I have applied throughout my app, but am now having trouble having to access children of the data with dynamic properties.
An export of my JSON data from my data base is;
{
"T&G Canary Wharf" : {
"Administrator" : {
"1550633367665" : {
"date" : "2019-02-12T12:00:00.000",
"details" : "Full Day",
"name" : "Edward Lawrence",
"status" : "pending"
},
"1550633370715" : {
"date" : "2019-02-13T12:00:00.000",
"details" : "Full Day",
"name" : "Edward Lawrence",
"status" : false
},
"1550845072137" : {
"date" : "2019-02-12T12:00:00.000",
"details" : "Full Day",
"name" : "Katie Prescott ",
"status" : 1
},
},
"Stylist" : {
"1551222170677" : {
"date" : "2019-02-19T12:00:00.000",
"details" : "Full Day",
"name" : "Stylist Stylist",
"status" : "pending"
}
}
}
}
Per user of the app, group
(in the above example T&G Canary Wharf) will always be set, but the subgroup
(in the example Administrator & Stylists) is dynamic for admins, and this is where I am struggling,
My code for my firebase database read is below:
I am using felgo(formerly v-play), a link to their firebase documentation is:
App {
property var adminModel: []
property var groupName //the group name is assigned onLoggedIn, in this example group name === T&G Canary Wharf
FirebaseDatabase {
onLoggedIn: {
firebaseDb.getValue("groups" + "/" + groupName, {
orderByValue: true
}, function(success, key, value) {
if(success){
console.log("ADMIN MODEL: " + JSON.stringify(value))
adminModel = value // my array where I intend to push the data too
}
})
}
}
}
I have been reading through;
access/process nested objects, arrays or JSON
(super helpful by the way) specifically the section of What if the property names are dynamic and I don't know them beforehand?
I can create two list entries, of Administrator
and Stylist
(the subGroups, but where the child key of this is also dynamic (the time the entry is created, e.g: "1550633367665"), I cannot seem to get further?
to create this model I have the code:
ListPage {
id: adminPage
model: Object.keys(adminModel)
delegate: SwipeOptionsContainer {
id: container
rightOption: SwipeButton {
anchors.fill: parent
backgroundColor: "red"
icon: IconType.trash
onClicked: {
container.hideOptions()
}
}
SimpleRow {
id: userRow
width: parent.width
text: modelData
}
}
}
My question is
How can I create a listView
with the delegates being any object containing a "status" : "pending"
- done in other areas using a loop of if (value[i].status === pending) { arr.push({...})}
, but whilst the subgroup (Stylist/Administrator)
is unknown, from the above database example there would be 2 list elements, but in reality will contain many more with multiple subGroup
's.
After doing getValue
from FireBase, it seems like you need to perform a few things:
"pending"
.It looks like you've already achieved Step 1 with Object.keys(adminModel)
. Now we'll take that a couple steps further with a for-loop (Step 2 √).
var subgroups = Object.keys(adminModel);
for (var i in subgroups) {
var subgroup = adminModel[subgroups[i]];
// ...
}
For convenience, we've defined subgroup_obj
which will store the data of a subgroup. E.g.
"Stylist": {
"1551222170677" : {
"date" : "2019-02-19T12:00:00.000",
"details" : "Full Day",
"name" : "Stylist Stylist",
"status" : "pending"
}
}
We then go on to Step 3, retrieving time entries by again using Object.keys()
but this time on the subgroup.
var timeEntries = Object.keys(subgroup);
Since Object.keys()
returns an array, we can accomplish Step 4 by using the filter()
array method to filter entries with a pending status.
var filteredEntries = timeEntries.filter(function(t) { return subgroup[t].status === "pending"; } );
With newer version of JS, you could do timeEntries.filter(t => subgroup[t].status === "pending")
but this doesn't seem to be fully supported by Qt yet.
And that's that. filteredEntries
gives us an array of time entries (e.g. [ "1551222170677" ]
) for each subgroup.
If you want the complete time entry object, you could use the map
array method to get
var filteredEntries2 = filteredEntries.map(function(t) { return subgroup[t]; });
which gives you an array of objects. So something like
[
{
date: "2019-02-19T12:00:00.000"
details: "Full Day"
name: "Stylist Stylist"
status: "pending"
}
]
Hope this helps!