#javascript #node.js #reactjs #mongodb #mongoose
Вопрос:
Я сталкиваюсь с проблемой, когда я получаю (ошибка типа: неопределенный не является объектом) при попытке вызвать атрибут объекта; однако эта ошибка возникает, когда она вызывается в функции возврата. Кроме того, ошибка возникает только при вызове атрибута объекта, а не самого объекта.
Я старался, чтобы включенный код был кратким; хотя я не совсем уверен, где возникает ошибка, поэтому может быть немного ненужной информации. Кроме того, в коде есть комментарии, в которых указано, где возникают и не возникают ошибки.
backend/models/course.js
import mongoose from 'mongoose';
const courseSchema = mongoose.Schema({
_id: Number,
fields: Array,
number: Number,
name: String,
minCredits: Number,
maxCredits: Number,
description: String,
isSaved: { type: Boolean, default: false },
});
const course = mongoose.model('courses', courseSchema);
export default course;
backend/controllers/course.js
import CourseData from '../models/course.js';
export const getSpecificCourse = async(req, res)=> {
try {
const selectedCourse = await CourseData.findOne({ _id: req.query.courseId });
res.status(200).json(selectedCourse);
} catch (error) {
res.status(404).json({ message: error.message});
}
}
backend/routes/course.js
import express from 'express';
import { getSpecificCourse } from '../controllers/courses.js';
const router = express.Router();
router.get('/courseId', getSpecificCourse);
export default router;
backend/server.js
import express from 'express';
import mongoose from 'mongoose';
import cors from 'cors';
import courseRoutes from './routes/courses.js';
const app = express();
app.use(express.json());
app.use(cors());
app.use('/courses', courseRoutes);
const PORT = process.env.PORT || 5000;
mongoose.connect(mongoUrl, {dbName: "dbName"}) // Hidden for privacy
.then(() => app.listen(PORT, () =>
console.log(`Connection is established and running on port: ${PORT}`)
)).catch((err) => console.log(err.message));
frontend/src/components/CoursePage.js
import React, { useEffect, useState } from 'react';
import { useParams } from "react-router-dom";
import axios from 'axios';
import './styles.css';
export function CoursePage() {
const [isLoading, setLoading] = useState(true);
const [course, setCourse] = useState()
const { courseId } = useParams()
const url = 'http://localhost:5000/courses/courseId/?courseId=' courseId;
useEffect(() => {
axios.get(url).then( (selectedCourse) => {
setCourse(selectedCourse.data);
setLoading(false);
} )
}, [])
console.log(course); // results in no error
console.log(course.number); // results in an error (occurs when calling any attribute)
if (isLoading) {
return <div>Loading...</div>
}
return (
<div>
{console.log(course)} // results in no error
{console.log(course.number)} // results in no error (consistent with each attribute)
</div>
);
}
Ответ №1:
Во-первых, загрузка состояний начинается как true, а курс начинается как неопределенный:
const [isLoading, setLoading] = useState(true);
const [course, setCourse] = useState()
А затем вы попытаетесь получить доступ к курсу до того, как он будет определен:
// now the course is not defined yet.
console.log(course); // results in no error
console.log(course.number); // results in an error (occurs when calling any attribute)
if (isLoading) {
return <div>Loading...</div>
}
Если вы измените код на:
if (isLoading) {
return <div>Loading...</div>
}
console.log(course); // results in no error
console.log(course.number); // results in an error (occurs when calling any attribute)
Ваш код go работает без каких-либо ошибок, потому что загрузка устанавливается в значение false только в том случае, если состояние курса установлено для полученного объекта.