Home > Blockchain >  Cannot list keys within object
Cannot list keys within object

Time:05-30

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:

enter image description here

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:

enter image description here

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:values. 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("=================");

  • Related