Home > Net >  Array data from Graphql is not populating a component in React
Array data from Graphql is not populating a component in React

Time:09-25

I am trying to render multiple checkboxes that have two functions:

  1. Show two states: checked and unchecked
  2. Update a checked array with the checked checkboxes

Currently, I am successfully able to accomplish these two goals with dummy data:

const dummyPlayers = [
    { id: 1, name: 'Puppa' },
    { id: 2, name: 'Korvo' },
    { id: 3, name: 'Jesse' },
    { id: 4, name: 'Terry' },
    { id: 5, name: 'Gobblins' }
  ]

This is the shape of the array I want to populate the checkboxes with:

[
    {
        "id": "936d6050-00df-4bd4-bc54-6ce58ad0210c",
        "name": "Travis",
        "owner": "moralesfam",
        "type": "Member",
        "createdAt": "2021-09-24T20:08:02.292Z",
        "updatedAt": "2021-09-24T20:08:02.292Z"
    }...
]

However, when I start pulling data in from a database with Graphql, while I am able to render the checkboxes to the DOM, they are not interactive (don't show checked state) and don't log the checked checkboxes.

I bring in the data, an array of objects through a custom React hook, called useMembers and the data is stored in a members array. Console logging members prints out the array, but as soon as I swap the dummyPlayers for the members array, the two goals I stated earlier are unsuccessful.

// RecordGame.js
import React, { useState } from 'react'

import useLoadMembers from '../hooks/useLoadMembers'
import useUser from '../hooks/useUser'


function RecordGame() {
  const dummyPlayers = [
    { id: 1, name: 'Puppa' },
    { id: 2, name: 'Korvo' },
    { id: 3, name: 'Jesse' },
    { id: 4, name: 'Terry' },
    { id: 5, name: 'Gobblins' },
  ]

  const { members } = useLoadMembers(updateLoading)
  const { user } = useUser()

  const [checkedState, setCheckedState] = useState(
    new Array(members.length).fill(false)
  )


  let playingPlayers = []
  for (var index in checkedState) {
    if (checkedState[index] === true) {
      playingPlayers.push(dummyPlayers[index])
    }
  }

  console.log(playingPlayers)

  const handleOnChange = (position) => {
    const updatedCheckedState = checkedState.map((player, index) =>
      index === position ? !player : player
    )
    setCheckedState(updatedCheckedState)
  }

  // Rendered elements
  const playerCheckboxes = dummyPlayers.map((player, index) => {
    return (
      <div key={index}>
        <label htmlFor={player.name}>
          <input
            type="checkbox"
            id={player.name}
            name={player.name}
            checked={checkedState[index]}
            onChange={() => handleOnChange(index)}
          />
          <span> {player.name}</span>
        </label>
      </div>
    )
  })

  return (
        <div>
          <form>
            {/* Game Players */}
            <div>
              <label htmlFor="players">
                Who Played?
              </label>
              <div>{playerCheckboxes}</div>
            </div>
          </form>
        </div>
      )}
    </Dashboard>
  )
}

export default RecordGame
//useLoadMember.js
import { useState, useEffect } from 'react'
import { API, Auth } from 'aws-amplify'
import { listMembers } from '../graphql/queries'

const useLoadMembers = (updateLoading) => {
  const [members, updateMembers] = useState([])

  useEffect(() => {
    fetchMembers()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  const fetchMembers = async () => {
    try {
      let memberData = await API.graphql({
        query: listMembers,
        variables: { limit: 100 },
      })

      updateLoading(false)

      let allMembers = memberData.data.listMembers.items
      setFilteredMembers(allMembers)
    } catch (err) {
      console.error(err)
    }
  }

  const setFilteredMembers = async (allMembers) => {
    const { username } = await Auth.currentAuthenticatedUser()
    const myMemberData = allMembers.filter((p) => p.owner === username)

    updateMembers(myMemberData)
  }

  return { members }
}

export default useLoadMembers

In this first, picture, I used the dummyPlayers array and got the results I wanted. enter image description here

However, in this second screenshot, I replaced the dummyData with the members array and did not get any results I wanted.

enter image description here

I'm just confused on why I am getting different results with the same array shape.

CodePudding user response:

wherever you use members you will need to check that members is not undefined before it gets used. If the api calls are not complete, it will get set initially as undefined.

eg: members && members.map(() => ....)

  • Related