Home > Net >  react js Cannot read properties of undefined (reading 'id')
react js Cannot read properties of undefined (reading 'id')

Time:05-15

import React, { useEffect, useState } from 'react'
import { createAPIEndpoint, ENDPOINTS, BASE_URL } from '../api'
import useStateContext from '../hooks/useStateContext'
import { useNavigate } from 'react-router'
import { Card, CardContent, CardMedia, CardHeader, List, ListItemButton, Typography, Box, LinearProgress } from '@mui/material'
import { getFormatedTime } from '../helper'

export default function Quiz() {

    const [qns, setQns] = useState([])
    const [answer, setAnswer] = useState([])
    const [qnIndex, setQnIndex] = useState(0)
    const [answerIndex, setAnswerIndex] = useState(0)
    const [timeTaken, setTimeTaken] = useState(0)
    const { context, setContext } = useStateContext()
    const navigate = useNavigate()

    let timer;

    const startTimer = () => {
        timer = setInterval(() => {
            setTimeTaken(prev => prev   1)
        }, [1000])
    }
    useEffect(() => {

        setContext({
            timeTaken: 0,
            selectedOptions: []
        })

        createAPIEndpoint(ENDPOINTS.question)
            .fetchById(context.examid)
            .then(res => {
                setQns(res.data)
                startTimer()
                createAPIEndpoint(ENDPOINTS.answer)
                    .fetchById(res.data[0].id)
                    .then(res => {
                        setAnswer(res.data)
                    })
                    .catch(err => { console.log(err); })
            })
            .catch(err => { console.log(err); })




    }, [])

    const updateAnswer = (qnId, length) => {

        console.log(qnId)
        // console.log(qns.length)

        const temp = [...context.selectedOptions]
        temp.push({
            questionId: qnId,

        })
        if (length <= qns.length) {
            setContext({ selectedOptions: [...temp] })
            setQnIndex(qnIndex   1)
            createAPIEndpoint(ENDPOINTS.answer)
                .fetchById(qnId   1)
                .then(res => {
                    setAnswer(res.data)
                    // console.log(res.data)
                })
                .catch(err => { console.log(err); })
        }
        else {
            setContext({ selectedOptions: [...temp], timeTaken })
            navigate("/result")
        }
    }

    return (
        qns.length != 0
            ?

            <Card
                sx={{
                    maxWidth: 640, mx: 'auto', mt: 5,
                    '& .MuiCardHeader-action': { m: 0, alignSelf: 'center' }
                }}>
                <CardHeader
                    title={'Question '   (qnIndex   1)   ' of '   qns.length}
                    action={<Typography>{getFormatedTime(timeTaken)}</Typography>} />
                <Box>
                    <LinearProgress variant="determinate" value={(qns[qnIndex].id) * 100 / qns.length} />
                </Box>

                <CardContent>
                    <Typography variant="h6">
                        {qns[qnIndex].id}
                    </Typography>
                    <List>
                        {answer.map((data, idx) => (

                            <ListItemButton disableRipple key={idx} onClick={() => updateAnswer(qns[qnIndex].id, idx)}>
                                <div>
                                    <b>{String.fromCharCode(65   idx)   " . "}</b>{data.title} {qns[qnIndex].id}
                                </div>

                            </ListItemButton>
                        ))}
                    </List>

                </CardContent>
            </Card>
            : null
    )
}

CodePudding user response:

I fixed this code:

                       <ListItemButton disableRipple key={idx} onClick={() => updateAnswer(data.questionId, idx)}>
                            <div>
                                <b>{String.fromCharCode(65   idx)   " . "}</b>{data.title} {data.questionId}
                            </div>

                        </ListItemButton>

CodePudding user response:

import React, { useEffect, useState } from 'react'
import { createAPIEndpoint, ENDPOINTS, BASE_URL } from '../api'
import useStateContext from '../hooks/useStateContext'
import { useNavigate } from 'react-router'
import { Card, CardContent, CardMedia, CardHeader, List, ListItemButton, Typography, Box, LinearProgress } from '@mui/material'
import { getFormatedTime } from '../helper'

export default function Quiz() {

    const [qns, setQns] = useState([])
    const [answer, setAnswer] = useState([])
    const [qnIndex, setQnIndex] = useState(0)
    const [answerIndex, setAnswerIndex] = useState(0)
    const [timeTaken, setTimeTaken] = useState(0)
    const { context, setContext } = useStateContext()
    const navigate = useNavigate()

    let timer;

    const startTimer = () => {
        timer = setInterval(() => {
            setTimeTaken(prev => prev   1)
        }, [1000])
    }
    useEffect(() => {

        setContext({
            timeTaken: 0,
            selectedOptions: []
        })

        createAPIEndpoint(ENDPOINTS.question)
            .fetchById(context.examid)
            .then(res => {
                setQns(res.data)
                startTimer()
                createAPIEndpoint(ENDPOINTS.answer)
                    .fetchById(res.data[0].id)
                    .then(res => {
                        setAnswer(res.data)
                    })
                    .catch(err => { console.log(err); })
            })
            .catch(err => { console.log(err); })




    }, [])

    const updateAnswer = (qnId, AnsId) => {

        console.log(qnId)
        // console.log(qns.length   'is '   'length is '   length)

        const temp = [...context.selectedOptions]
        temp.push({
            questionId: qnId,
            answerId: AnsId

        })
        if (qnId < qns.length) {
            setContext({ selectedOptions: [...temp] })
            setQnIndex(qnIndex   1)
            createAPIEndpoint(ENDPOINTS.answer)
                .fetchById(qnId   1)
                .then(res => {
                    setAnswer(res.data)
                    // console.log(res.data)
                })
                .catch(err => { console.log(err); })
        }
        else {
            setContext({ selectedOptions: [...temp], timeTaken })
            navigate("/result")
        }
    }

    return (
        qns.length != 0
            ?

            <Card
                sx={{
                    maxWidth: 640, mx: 'auto', mt: 5,
                    '& .MuiCardHeader-action': { m: 0, alignSelf: 'center' }
                }}>
                <CardHeader
                    // title={'Question '   (qnIndex   1)   ' of '   qns.length}
                    action={<Typography>{getFormatedTime(timeTaken)}</Typography>} />
                <Box>
                    {/* <LinearProgress variant="determinate" value={(qns[qnIndex].id) * 100 / qns.length} /> */}
                </Box>

                <CardContent>
                    <Typography variant="h6">
                        {/* {qns[qnIndex].id} */}
                    </Typography>
                    <List>
                        {answer.map((data, idx) => (

                            <ListItemButton disableRipple key={idx} onClick={() => updateAnswer(data.questionId, data.id)}>
                                <div>
                                    <b>{String.fromCharCode(65   idx)   " . "}</b>{data.title} {data.questionId}
                                </div>

                            </ListItemButton>
                        ))}
                    </List>

                </CardContent>
            </Card>
            : null
    )
}
  • Related