1

I have a table in which I map some data to it, on + button I want to add new table row and set new defaultState for that table row using react hook

import React, { useState, useEffect } from 'react'
import { useMutation, useQuery } from '@apollo/react-hooks'
import { Link, useParams } from 'react-router-dom'

import './style.css'
import {
  GET_SURVEY,
  CREATE_SURVEY,
} from './queries'
import { pushError } from '../../modules/error'

export default function SurveyDetails() {
  const params = useParams()
  const { data } = useQuery(GET_SURVEY, { variables: { id: params.surveyId } })
  const [survey, setSurvey] = useState({})
  useEffect(() => {
    async function loadSurvey() {
      if (data && data.me.survey) {
        await setSurvey(data.me.survey)
      }
    }
    loadSurvey()
  }, [data])

  const HomePage = () => (
    <Link to="/home">Home</Link>
  )
  const SurveyPage = () => (
    <Link to="/survey">Survey</Link>
  )

  const hadnleAddRow = () => {
    console.log('?????')
    const questionId = (survey.questions || []).map((t) => t.id)
    const newState = {
      id: params.surveyId,
      questions: {
        id: questionId,
        questionText: '',
        type: '',
        options: [],
      }
    }
    // console.log(setSurvey((preSurvey) => [...preSurvey, {}]))
    setSurvey((preSurvey) => [...preSurvey, newState])
  }

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between' }}>
        <h2>Survey Details</h2>
        <div style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center', flex: '1' }}>
          <span style={{ paddingRight: '25px' }}><SurveyPage /></span>
          <span><HomePage /></span>
        </div>
      </div>
      <table>
        <tr>
          <th>Question Text</th>
          <th>Type</th>
          <th>Options</th>
          <th>Status</th>
          <th>Edit</th>
          <th><button type="submit" onClick={hadnleAddRow}>+</button></th>
          <th>Remove</th>
        </tr>
        {(survey.questions || []).map((q) => (
          <tr key={q.id}>
            <td>{ q.questionText }</td>
            <td>{ q.type }</td>
            <td>
              { q.options.join(', ')}
              {' '}
            </td>
            <td>{ survey.status }</td>
            <td><button type="submit" onClick={openModal}>Edit</button></td>
            <td />
            <td><button type="submit">-</button></td>
          </tr>
        ))}
      </table>
    </div>
  )
}

Right now the error I'm facing is this

TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
  81 |     }
  82 |   }
  83 |   // console.log(setSurvey((preSurvey) => [...preSurvey, {}]))
> 84 |   setSurvey((preSurvey) => [...preSurvey, newState])
     | ^  85 | }
  86 | 
  87 | return (

Can someone please explain to me what is happening here, thanks.

1 Answer 1

1

survey is an object having questions as an array(Am i right on this?)

You are returning array with setSurvey.

setSurvey((preSurvey) => {questions:[...preSurvey.questions, newState]})
Sign up to request clarification or add additional context in comments.

4 Comments

yup, object whit question as an array, but this will result in another error Expected an assignment or function call and instead saw an expression no-unused-expressions but I see your point here
const questionId = (survey.questions || []).map((t) => t.id) . I am confused with what you did here. This is an array and you are assigning this to id. Can you clarify on this?
trying to fetch id which is already there, I've solved it should go setSurvey((preSurvey) => [...preSurvey.questions, newState]) you're hint helped me
Glad it was a help for you :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.