我的代码以前工作时,MySQL中的两个表都只是"id";。为了增加更多的特异性并能够添加外键,我将两个表中的id更改为:
bugtracker_table:id-->project_id
ticket_table:id-->ticket_id
现在,我突然得到了一个错误:未捕获的类型错误:projects.map不是函数-在Dashboard.js的第25行上(下面突出显示(,在我的应用程序完美工作之前。
Dashboard.js
import React, { useState, useEffect } from "react";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { Button } from "primereact/button";
// import ButtonDemo from './ButtonDemo';
import { Chart } from "primereact/chart";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
import axios from "axios";
import { useHistory, Link } from "react-router-dom";
import { Dialog } from "primereact/dialog";
// import { Media } from "react-bootstrap/Media"
// import ProjectsTable from "./Tables/ProjectsTable";
// import TicketsPieChart from "./Tables/TicketsPieChart"
// import API from
//project table
//eslint-disable no-unused-vars
const TableDemo = () => {
const [project_name, setProjectName] = useState("");
const [description, setDescription] = useState("");
const [projects, setProjects] = useState([]);
const history = useHistory();
Line 25 const projectsToShow = projects.map(project => {
return {
...project,
project_name: <Link to={`/projects/${project.project_id}`}>{project.project_name}</Link>,
};
});
useEffect(() => {
getProjects();
}, []);
const [displayResponsive, setDisplayResponsive] = useState(false);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/bugtracker_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/bugtracker_table", {
project_name: project_name,
description: description,
});
history.push("/");
};
const dialogFuncMap = {
displayResponsive: setDisplayResponsive,
};
const onClick = (name) => {
dialogFuncMap[`${name}`](true);
};
const onHide = (name) => {
dialogFuncMap[`${name}`](false);
};
const renderFooter = (name) => {
return (
<div>
{" "}
<Button onClick={saveProject} type="submit" label="Submit" className="p-button-rounded p-button-success mr-2 mb-2 success" />
</div>
);
};
// const paginatorLeft = <Button type="button" icon="pi pi-refresh" className="p-button-text" />;
// const paginatorRight = <Button type="button" icon="pi pi-cloud" className="p-button-text" />;
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Projects</h5>
<div>
<Button className="p-button-rounded mr-2 mb-2 npbutton" label="New Ticket" onClick={() => onClick("displayResponsive")} />
</div>
<Dialog className="dialogModal" header="Create Ticket" visible={displayResponsive} onHide={() => onHide("displayResponsive")} breakpoints={{ "960px": "75vw" }} style={{ width: "35vw" }} footer={renderFooter("displayResponsive")}>
<form>
<h5>Project Name</h5>
<InputText value={project_name} onChange={(e) => setProjectName(e.target.value)} type="text" placeholder="Enter project name"></InputText>
<h5>Project Description</h5>
<InputTextarea value={description} onChange={(e) => setDescription(e.target.value)} type="text" placeholder="Enter project description" autoResize rows="4" cols="40" />
</form>
</Dialog>
{/* // <Link to="/ticketlist" className="col-12"> */}
<div>
{/* // className="card"></Link> */}
<DataTable
// sortMode="single" sortField="representative.name"
editMode="row"
value={projectsToShow}
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
paginator
paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords}"
rows={5}
rowsPerPageOptions={[5, 10, 25]}
>
{/* // paginatorLeft={paginatorLeft} paginatorRight={paginatorRight}> */}
<Column field="project_name" header="Project Name" style={{ minWidth: "200px" }}></Column>
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="createdAt" header="Created On" style={{ minWidth: "150px" }}></Column>
{projects.map((project, index) => (
<tr key={project.project_id}>
<td>{index + 1}</td>
<td>{project.description}</td>
<td>{project.createdAt}</td>
</tr>
))}
</DataTable>
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Type</h5>
<Chart type="pie" focus={"type"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Priority</h5>
<Chart type="pie" focus={"priority"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Status</h5>
<Chart type="pie" focus={"status"} />
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(TableDemo);
我想,因为我更改了MySQL中的id名称,所以我也需要调整后端的id名称,所以我尝试将以前它说id的地方更改为现在的project_id,但我认为我做得不对,并认为这就是错误的来源。
后端/控制器/products.js
import Project from "../models/productModel.js";
export const getAllProjects = async (req, res) => {
try {
const projects = await Project.findAll();
res.json(projects);
} catch (error) {
res.json({ message: error.message });
}
}
export const getProjectsById = async (req, res) => {
try {
const project = await Project.findAll({
where: {
project_id: req.params.id
}
});
res.json(project[0]);
} catch (error) {
res.json({ message: error.message });
}
}
export const createProject = async (req, res) => {
try {
await Project.create(req.body);
res.json({
"message": "Project Created"
});
} catch (error) {
res.json({ message: error.message });
}
}
export const updateProject = async (req, res) => {
try {
await Project.update(req.body, {
where: {
project_id: req.params.id
}
});
res.json({
"message": "Project Updated"
});
} catch (error) {
res.json({ message: error.message });
}
}
export const deleteProject = async (req, res) => {
try {
await Project.destroy({
where: {
project_id: req.params.id
}
});
res.json({
"message": "Project Deleted"
});
} catch (error) {
res.json({ message: error.message });
}
}
backend/routes/index.js
import express from "express";
import { getAllProjects, createProject, getProjectsById, updateProject, deleteProject } from "../controllers/Products.js";
const router = express.Router();
router.get("/", getAllProjects);
router.get("/:project_id", getProjectsById);
router.post("/", createProject);
router.patch("/:project_id", updateProject);
router.delete("/:project_id", deleteProject);
/后端/模型/ProductModels.js
import { Sequelize } from "sequelize";
import db from "../config/database.js";
const { DataTypes } = Sequelize;
const Project = db.define('bugtracker_table',{
project_name:{
type: DataTypes.STRING
},
description:{
type: DataTypes.STRING
},
createdAt:{
type: DataTypes.DATE
}
},{
freezeTableName: true
});
export default Project;
backend/database.js
import { Sequelize } from "sequelize";
const db = new Sequelize('bugtracker_db', 'root', '', {
host: "localhost",
dialect: "mysql",
port: 8889,
username: "root",
password: "root",
});
export default db;
Uncaught TypeError: projects.map is not a function
表示分配给projects
的变量不是数组,因为map函数仅在数组上可用。
如果你看一下你从http://localhost:5002/bugtracker_table
得到的响应,你几乎肯定会发现这个数据不是一个数组。事实上,您没有对应于/bugtracker_table
的路由。
尝试更改您的路线文件,如下面的
router.get("/bugtracker_table", getAllProjects);
router.get("/:project_id", getProjectsById);
router.post("/bugtracker_table", createProject);
router.patch("/:project_id", updateProject);
router.delete("/:project_id", deleteProject);
因此,现在您的getAllProjects路由与您在React中调用的路由相匹配。