无法读取未定义的属性(读取 'fitness')
Cannot read properties of undefined (reading 'fitness')
我们目前正在为我们的室友配对项目制作一个网站。我们正处于制作结果页面的阶段,该页面应根据算法计算其兼容性百分比的一些问题显示 3 个最兼容的室友。
我们现在正尝试传递名为“fitness”的对象,该对象包含所有结果,即:
let fit = {
fitness: Math.round(sum * 100),
email: resident[i].email,
name: resident[i].firstName + " " + resident[i].lastName,
};
到我们名为 results.ejs 的 .ejs 文件。 fit 对象被推入我们的全局“fitness”变量。
这是我们的 post 请求:
router.post("/results", function (request, response) {
let item = request.body;
let applicant_name = request.body.firstName;
client.connect(function (err) {
const db = client.db("myFirstDatabase");
assert.equal(null, err);
db.collection("residents").insertOne(item, function (err, result) {
assert.equal(null, err);
console.log("Item inserted");
});
});
client.connect(function (err) {
const db = client.db("myFirstDatabase");
assert.equal(null, err);
db.collection("residents")
.find({})
.toArray(function (err, resident) {
if (err) throw err;
/* weighting(request); */
compatability(request, resident);
});
});
client.close();
response.render("pages/results", {
applicant_name: applicant_name,
resident: fitness,
});
});
在我们的 results.ejs 文件中,我们使用 Bootstrap 卡片来显示 3 个最合适的室友。这是我们在 results.ejs 文件中使用的代码:
<p class="card-text">
Compatibility %: <%= resident[0].fitness %><br />
Name: <%= resident[0].name %> <br />
Email: <%= resident[0].email %><br />
Location: <br />
</p>
每当我们运行 post 请求时,我们都会收到一条错误消息“无法读取未定义的属性(读取'fitness')”,但是如果我们再次刷新,Node.js 服务器崩溃,但它显示了我们想要获得的实际值。如果我们加一个“?”在“resident[0]”之后,运行页面没有任何错误,但不显示来自对象的任何信息。
我们尝试了很多事情,但找不到解决此问题的正确方法。
提前致谢。
编辑
来自 .ejs 文件和我们的服务器端代码的完整代码,以及它在网站上的外观照片:https://pastebin.com/zRxdk6aq
本例中的错误"Cannot read properties of undefined (reading 'fitness')"
表示resident[0]
未定义。这可能是由于 resident
未定义或者是一个空数组(长度为 0)。
从您提供的代码中我看不到,您实际将对象推入全局 fitness 变量的位置或定义变量的位置。也许这就是问题所在。为了进一步帮助您,如果您能 post 代码肯定会有所帮助。
编辑:
查看您在 pastebin 中提供的新代码,看起来您正在使用异步函数,但期待同步行为。您当前的代码基本上如下所示:
router.post("/results", function (request, response) {
client.connect(function (err) {
// Insert data into db
});
client.connect(function (err) {
// Fetch data from db
});
client.close();
response.render("pages/results", {
applicant_name: applicant_name,
resident: fitness,
});
});
问题在于,您的程序不会等待 DB-operations 完成后再呈现您的页面。这是因为 callback functions work.
我假设您正在使用 nodejs 的 mongoDB 驱动程序。除了经典的回调选项,它还允许使用 async/await:
router.post("/results", async (request, response) {
//
await client.connect();
const db = client.db('myFirstDatabase');
await db.collection("residents").insertOne(request.body);
let residents = await db.collection("residents").find({}).toArray();
let fitness = compatability(request, resident);
client.close();
response.render("pages/results", {
applicant_name: request.body.firstName,
resident: fitness,
});
});
function compatability(request, resident) {
let fitness = [];
// Do your calculations here
return fitness;
}
这样您的请求处理程序就会一直等待,直到您将新项目插入数据库并获取现有项目。只有在那之后,它才会呈现您的页面,从而确保 fitness
变量已经填充了数据。
请注意,在此示例中,我还建议更改您的兼容性函数,以便它 returns 您的“适合度”变量,而不是使其成为全局变量。
如果您不熟悉 async/await,我建议您也尝试了解 Promises。
我们目前正在为我们的室友配对项目制作一个网站。我们正处于制作结果页面的阶段,该页面应根据算法计算其兼容性百分比的一些问题显示 3 个最兼容的室友。
我们现在正尝试传递名为“fitness”的对象,该对象包含所有结果,即:
let fit = {
fitness: Math.round(sum * 100),
email: resident[i].email,
name: resident[i].firstName + " " + resident[i].lastName,
};
到我们名为 results.ejs 的 .ejs 文件。 fit 对象被推入我们的全局“fitness”变量。
这是我们的 post 请求:
router.post("/results", function (request, response) {
let item = request.body;
let applicant_name = request.body.firstName;
client.connect(function (err) {
const db = client.db("myFirstDatabase");
assert.equal(null, err);
db.collection("residents").insertOne(item, function (err, result) {
assert.equal(null, err);
console.log("Item inserted");
});
});
client.connect(function (err) {
const db = client.db("myFirstDatabase");
assert.equal(null, err);
db.collection("residents")
.find({})
.toArray(function (err, resident) {
if (err) throw err;
/* weighting(request); */
compatability(request, resident);
});
});
client.close();
response.render("pages/results", {
applicant_name: applicant_name,
resident: fitness,
});
});
在我们的 results.ejs 文件中,我们使用 Bootstrap 卡片来显示 3 个最合适的室友。这是我们在 results.ejs 文件中使用的代码:
<p class="card-text">
Compatibility %: <%= resident[0].fitness %><br />
Name: <%= resident[0].name %> <br />
Email: <%= resident[0].email %><br />
Location: <br />
</p>
每当我们运行 post 请求时,我们都会收到一条错误消息“无法读取未定义的属性(读取'fitness')”,但是如果我们再次刷新,Node.js 服务器崩溃,但它显示了我们想要获得的实际值。如果我们加一个“?”在“resident[0]”之后,运行页面没有任何错误,但不显示来自对象的任何信息。 我们尝试了很多事情,但找不到解决此问题的正确方法。 提前致谢。
编辑
来自 .ejs 文件和我们的服务器端代码的完整代码,以及它在网站上的外观照片:https://pastebin.com/zRxdk6aq
本例中的错误"Cannot read properties of undefined (reading 'fitness')"
表示resident[0]
未定义。这可能是由于 resident
未定义或者是一个空数组(长度为 0)。
从您提供的代码中我看不到,您实际将对象推入全局 fitness 变量的位置或定义变量的位置。也许这就是问题所在。为了进一步帮助您,如果您能 post 代码肯定会有所帮助。
编辑: 查看您在 pastebin 中提供的新代码,看起来您正在使用异步函数,但期待同步行为。您当前的代码基本上如下所示:
router.post("/results", function (request, response) {
client.connect(function (err) {
// Insert data into db
});
client.connect(function (err) {
// Fetch data from db
});
client.close();
response.render("pages/results", {
applicant_name: applicant_name,
resident: fitness,
});
});
问题在于,您的程序不会等待 DB-operations 完成后再呈现您的页面。这是因为 callback functions work.
我假设您正在使用 nodejs 的 mongoDB 驱动程序。除了经典的回调选项,它还允许使用 async/await:
router.post("/results", async (request, response) {
//
await client.connect();
const db = client.db('myFirstDatabase');
await db.collection("residents").insertOne(request.body);
let residents = await db.collection("residents").find({}).toArray();
let fitness = compatability(request, resident);
client.close();
response.render("pages/results", {
applicant_name: request.body.firstName,
resident: fitness,
});
});
function compatability(request, resident) {
let fitness = [];
// Do your calculations here
return fitness;
}
这样您的请求处理程序就会一直等待,直到您将新项目插入数据库并获取现有项目。只有在那之后,它才会呈现您的页面,从而确保 fitness
变量已经填充了数据。
请注意,在此示例中,我还建议更改您的兼容性函数,以便它 returns 您的“适合度”变量,而不是使其成为全局变量。
如果您不熟悉 async/await,我建议您也尝试了解 Promises。