I have a state variable projects
which should store a dictionary of arrays, where the key is id of the organisation that owns the project, and the array consists of objects storing information about the project. For example:
{
orgId123: [
project1: {
name: "my cool project",
status: "submitted"
},
projectAwesome: {
name: "Stan's project",
status: "draft"
}
],
orgUSA: [
newProj234: {
name: "another great project",
status: "submitted"
}
]
}
I try to get a list of all organisation IDs using Objects.keys(projects)
, however that returns an empty array.
I suspect that somehow my projects
variable is structured wrongly. When I console.log
the contents of projects
, I get:
Notice how the root level object says just {}
.
When I tried to re-create what the projects
variable should look like and logged that, I saw a slightly different output:
In this manually created object, the root-level object is shown as {orgId1}: Array(1)
instead of the previously-shown {}
(on the actual object).
What does this say about how the object is structured and why can I not get a list of keys from the first object using Object.keys()
?
For context, I create the original variable using the following code:
async function fetchProjects() {
// Load list of organisations that the user is a member of
const organisationsSnapshot = await getDocs(query(
collection(db, 'organisations'),
where(`members.${user.uid}`, '!=', null)
))
const organisations = organisationsSnapshot.docs.map(organisationSnap => ({
...organisationSnap.data(),
id: organisationSnap.id
}))
// Load list of projects for each organisation the user is a member of
const projectsDict = {}
organisations.forEach(async (organisation) => {
const projectsQuery = query(collection(db, `organisations/${organisation.id}/projects`))
const projectsSnap = await getDocs(projectsQuery)
projectsDict[organisation.id] = projectsSnap.docs.map(projectSnap => ({
...projectSnap.data(),
id: projectSnap.id
}))
})
setProjects(projectsDict)
}
CodePudding user response:
You cannot have an array of key:value
s. You should wrap it in {}
.
[ key1: value1, key2: value2, ] //Unexpected Token
[ { key1: value1 }, { key2: value2 }, ] //Good to go
So instead of:
{
orgId123: [
project1: {
name: "my cool project",
status: "submitted"
},
projectAwesome: {
name: "Stan's project",
status: "draft"
}
],
orgUSA: [
newProj234: {
name: "another great project",
status: "submitted"
}
]
}
You should have:
{
orgId123: [
{
project1: {
name: "my cool project",
status: "submitted"
}
},
{
projectAwesome: {
name: "Stan's project",
status: "draft"
}
}
],
orgUSA: [
{
newProj234: {
name: "another great project",
status: "submitted"
}
}
]
}
OR
{
orgId123: {
project1: {
name: "my cool project",
status: "submitted"
},
projectAwesome: {
name: "Stan's project",
status: "draft"
}
},
orgUSA: {
newProj234: {
name: "another great project",
status: "submitted"
}
}
}
Honestly, I would structure your projects
as follows:
const organisations = [{
orgId: "orgId123",
projects: [{
projectId: "project1",
name: "my cool project",
status: "submitted"
}, {
projectId: "projectAwesome",
name: "Stan's project",
status: "draft"
}]
},
{
orgId: "orgUSA",
projects: [{
projectId: "newProj234",
name: "another great project",
status: "submitted"
}]
}
]
//This way, organisations is an array of organisations,
//which is an object that has orgId, projects which is an array of its projects.
//It will be much more intuitive to work with while iterating over it.
//Such as if you need to display all the orgIds,
console.log("Organisation IDs:")
for (const org of organisations) {
console.log(org.orgId)
}
console.log("=================");
//If you need all project IDs and names:
console.log("Projects:")
for (const org of organisations) {
console.log(`Organisation ${org.orgId} has the following projects:`)
for (const proj of org.projects) {
console.log(`Project ID ${proj.projectId}: ${proj.name}`)
}
console.log("=================");
}
console.log("=================");