I'm using ExpressJS and I have a problem where the .equals()
method is not recognized. The two objects are of different types, but both have the same value. I modified the operator to ==
, but it continuously jumps to the else statement.
I want to know 'how' I can pare these two parameters and how I can correct the error in the if
statement with the objective being that I ensure that a user can edit a profile if
they are the owner.
Here is my code along with the output and the database. Thank you in advance for your assistance.
====================== Problem SOLVED
the code:.............................................................
app.use("/teachers/:id/editProfile", function (req, res ){
if(req.isAuthenticated()){
Teacher.findById(req.params.id, function(err , foundTeacher){
if(err){
res.redirect("/teachers");
}else{
console.log("WHAT ! " + foundTeacher._id );
console.log("WHAT ! " + req.user.profile );
if(req.user.profile.equals(foundTeacher._id) ){
res.send("YOU HAVE PERM ............");
}else{
res.send("YOU DO NOT HAVE PERMISSION TO DO THAT");
}
}
})
}else{
res.send("YOU NEED TO BE LOGGED IN TO DO THAT");
}
the output:.................................................................
WHAT ! 5c8b73b2e9b9ec2179224ef4
WHAT ! 5c8b73b2e9b9ec2179224ef4
events.js:160
throw er; // Unhandled 'error' event
^
TypeError: req.user.profile.equals is not a function
at /home/ubuntu/workspace/LearnFaceToFace/app.js:211:41
at /home/ubuntu/workspace/LearnFaceToFace/node_modules/mongoose/lib/model.js:4719:16
at /home/ubuntu/workspace/LearnFaceToFace/node_modules/mongoose/lib/query.js:4099:12
at process.nextTick (/home/ubuntu/workspace/LearnFaceToFace/node_modules/mongoose/lib/query.js:2681:28)
at _binedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
mongoose DB:................................................................
db.teachers.find()
{ "_id" : ObjectId("5c8b73b2e9b9ec2179224ef4"), "name" : "mr.s", "teachingField" : "math", "price" : "111$", "contact" : "[email protected]", "note" : "best page", "sex" : "male", "image" : ":ANd9GcSx2puLa7PoZiDMIAGChIP73M6NhfchM6A8ia_ZQXwmGP6IdtlnAw", "__v" : 0 }
db.users.find()
{ "_id" : ObjectId("5c8b73a6e9b9ec2179224ef3"), "profile" : [ ObjectId("5c8b73b2e9b9ec2179224ef4") ], "username" : "s1", "salt" : "e1c55598efe775b66bbf95ed7978e8ec410d8d2983823336eb6f59ac28ddfb6c", "hash" : "3bd7c4e2d2aab447919225a635cf8452afab8162dcf105c6508a1a646f497ddea21c922ae870a9364a2b93317d64802a0c59fe5aafa9cf94cc331a1e3b91fff2c503ab4e4c9939c348f5ff7be447292005bc80b661594e8bbff32eb425958b713e2545af33c06f963996aba85317f766c4c5a2942d85de86efd4dae8e15c46a4e7483853947ff5ec34595fbbec1ead920992aeff7a2bf84451207cd12123f586292a6e8a35d0ddb83cd2c99c9159511e82a3a28a4a5ceec6e9b7125df801800c8b78d417b411ff7478b200dfa746e9ee05a034e186c8670eba0984eb20610a16bad9cd823c21dadb9d9c1193b06d69cab85c00f1679025de66b16aecfc045618b69091fe556b1400737778558ff10f6030b39d98441ea00e33bb38a03303feaadf1493d0e4f9a3f048f98263d89994abc9ce97f8633976824248631e8fbcd02b502e8bc5e98c55dc0c8cedfbfab799a3de5a1ebcdd9c1f2f084b230a2f48da016b6000f9314052b8e1c4445023b9241167e0fce9db54f849c5face9fb39e4a56f2b78f61e80f5d74680c407e6cd61fb3249dab8f93f8bdf9cb59372879fffc4ffb14c84f3ab2e064240efc13b82d6f9ec79b8a6ccdebf8581ab1d4cb9275a42b04718b3ad56adca90e7cc434ff64afd4cfe35c80c32ea57b4e2f80be779b0dd64116c8006cacc64ab5d81c78100f8a29664960a14bfd40ad16e4a58e7d3540df", "__v" : 1 }
the user Schema ....................................................
var UserSchema = new mongoose.Schema({
username: String,
password: String,
profile:[
{type: mongoose.Schema.Types.ObjectId,
ref: "profile"
}]
});
I'm using ExpressJS and I have a problem where the .equals()
method is not recognized. The two objects are of different types, but both have the same value. I modified the operator to ==
, but it continuously jumps to the else statement.
I want to know 'how' I can pare these two parameters and how I can correct the error in the if
statement with the objective being that I ensure that a user can edit a profile if
they are the owner.
Here is my code along with the output and the database. Thank you in advance for your assistance.
====================== Problem SOLVED
the code:.............................................................
app.use("/teachers/:id/editProfile", function (req, res ){
if(req.isAuthenticated()){
Teacher.findById(req.params.id, function(err , foundTeacher){
if(err){
res.redirect("/teachers");
}else{
console.log("WHAT ! " + foundTeacher._id );
console.log("WHAT ! " + req.user.profile );
if(req.user.profile.equals(foundTeacher._id) ){
res.send("YOU HAVE PERM ............");
}else{
res.send("YOU DO NOT HAVE PERMISSION TO DO THAT");
}
}
})
}else{
res.send("YOU NEED TO BE LOGGED IN TO DO THAT");
}
the output:.................................................................
WHAT ! 5c8b73b2e9b9ec2179224ef4
WHAT ! 5c8b73b2e9b9ec2179224ef4
events.js:160
throw er; // Unhandled 'error' event
^
TypeError: req.user.profile.equals is not a function
at /home/ubuntu/workspace/LearnFaceToFace/app.js:211:41
at /home/ubuntu/workspace/LearnFaceToFace/node_modules/mongoose/lib/model.js:4719:16
at /home/ubuntu/workspace/LearnFaceToFace/node_modules/mongoose/lib/query.js:4099:12
at process.nextTick (/home/ubuntu/workspace/LearnFaceToFace/node_modules/mongoose/lib/query.js:2681:28)
at _binedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
mongoose DB:................................................................
db.teachers.find()
{ "_id" : ObjectId("5c8b73b2e9b9ec2179224ef4"), "name" : "mr.s", "teachingField" : "math", "price" : "111$", "contact" : "[email protected]", "note" : "best page", "sex" : "male", "image" : "https://encrypted-tbn0.gstatic./images?q=tbn:ANd9GcSx2puLa7PoZiDMIAGChIP73M6NhfchM6A8ia_ZQXwmGP6IdtlnAw", "__v" : 0 }
db.users.find()
{ "_id" : ObjectId("5c8b73a6e9b9ec2179224ef3"), "profile" : [ ObjectId("5c8b73b2e9b9ec2179224ef4") ], "username" : "s1", "salt" : "e1c55598efe775b66bbf95ed7978e8ec410d8d2983823336eb6f59ac28ddfb6c", "hash" : "3bd7c4e2d2aab447919225a635cf8452afab8162dcf105c6508a1a646f497ddea21c922ae870a9364a2b93317d64802a0c59fe5aafa9cf94cc331a1e3b91fff2c503ab4e4c9939c348f5ff7be447292005bc80b661594e8bbff32eb425958b713e2545af33c06f963996aba85317f766c4c5a2942d85de86efd4dae8e15c46a4e7483853947ff5ec34595fbbec1ead920992aeff7a2bf84451207cd12123f586292a6e8a35d0ddb83cd2c99c9159511e82a3a28a4a5ceec6e9b7125df801800c8b78d417b411ff7478b200dfa746e9ee05a034e186c8670eba0984eb20610a16bad9cd823c21dadb9d9c1193b06d69cab85c00f1679025de66b16aecfc045618b69091fe556b1400737778558ff10f6030b39d98441ea00e33bb38a03303feaadf1493d0e4f9a3f048f98263d89994abc9ce97f8633976824248631e8fbcd02b502e8bc5e98c55dc0c8cedfbfab799a3de5a1ebcdd9c1f2f084b230a2f48da016b6000f9314052b8e1c4445023b9241167e0fce9db54f849c5face9fb39e4a56f2b78f61e80f5d74680c407e6cd61fb3249dab8f93f8bdf9cb59372879fffc4ffb14c84f3ab2e064240efc13b82d6f9ec79b8a6ccdebf8581ab1d4cb9275a42b04718b3ad56adca90e7cc434ff64afd4cfe35c80c32ea57b4e2f80be779b0dd64116c8006cacc64ab5d81c78100f8a29664960a14bfd40ad16e4a58e7d3540df", "__v" : 1 }
the user Schema ....................................................
var UserSchema = new mongoose.Schema({
username: String,
password: String,
profile:[
{type: mongoose.Schema.Types.ObjectId,
ref: "profile"
}]
});
Share
Improve this question
edited Mar 16, 2019 at 2:49
Anas
asked Mar 15, 2019 at 22:05
AnasAnas
431 gold badge1 silver badge10 bronze badges
1
- maybe some of your users have profiles, and some don't? - check if it exists before using it - although you'd also need to decide what to do if a user doesn't have a profile – Robbie Commented Mar 15, 2019 at 22:20
2 Answers
Reset to default 3Ok, first things first. When something goes wrong, and you decide to debug it with console.log, NEVER use +
. Yes, I know it's beneficial to get some label on that data, but here's the trick: this...
console.log('SOME_LABEL:', some_data);
... will give you more-o-less detailed info about this data. And this...
console.log('SOME_LABEL:' + some_data);
... will always show you a string - result of concatenation of SOME_LABEL string and some_data cast to string. And yes, in JS something cast to string is not the same as representation of this something.
In fact, that's exactly the problem here. Both checked values are not strings - they are objects(*). And unless you have the same object on both side of ==
or ===
, you should always expect to get false
from that operation. Again, that's the case here.
Yes, there are utility methods on some libraries (_.isEqual) that allow you to pare objects by value, but those methods are called essentially as standalone functions and do not bee available on all objects automatically. And there's a reason for that.
Usually when you do need to pare two objects of same type (class), you better either implement some parison method on them or pare them cast to primitives. Otherwise you'll end up checking again and again both useful properties and something that's not really needed to be pared.
In this particular case, there's a property on ObjectId
just for that parison purpose - str:
str
Returns the hexadecimal string representation of the object.
So one possible approach to make the check is this:
if (req.user.profile.str === foundTeacher._id.str) { ... }
*Ok, foundTeacher._id
is ObjectId, but you'd better double-check what req.user.profile
actually is. If it's a string, just drop that str
property check.
You should actually try doing it the other way around.
foundTeacher._id.equals(req.user.profile)
"===" or "==" operators won't work in this case as one of the ids is a String and other one is mongodb objectid so you have to use the method provided by mongoose to pare these to values.