When I run this code, it returns an error saying that err is not defined
here is my code
app.post('/tinder/cards', (req, res) => {
const dbCard = req.body;
Cards.create(dbCard, (err, data) => {
if (err) {
res.status(500).send(err);
} else {
res.status(201).send(data);
}
});
app.get('/tinder/cards', (req, res) => {
Cards.find(err, data => {
if (err) {
res.status(500).send(err);
} else {
res.status(200).send(data);
}
});
Here is my definition of the MongoDB schema:
import mongoose from 'mongoose';
const cardSchema = mongoose.Schema({
name: String,
imgUrl: String,
});
export default mongoose.model('cards', cardSchema);
Someone, please help me fix this thank you!
Change
Cards.find(err, data =>
here it's looking for the filter/query as the 1st Parameter which err variable which is not defined so you're getting the ReferenceError.
To
Cards.find(query, (err, data) => { // 1st Parameter should be filter/query
https://mongoosejs.com/docs/api.html#model_Model.find
Model.find()
Parameters
filter «Object|ObjectId»
[projection] «Object|String|Array<String>» optional fields to return, see Query.prototype.select()
[options] «Object» optional see Query.prototype.setOptions()
[callback] «Function»
Related
I created an simple CRUD operation in nodejs and mongoose. Updating an user using RESTAPI.
an error message in Insomnia
Error: Server returned nothing (no headers, no data)
URL
http://localhost:1337/api/users/update/63ab9b716065482273e58b75
#PUT METHOD
router.put("/update/:id",updateUser)
const updateUser = async (req,res,next) => {
if (req.params.id === req.user.id) {
try {
const updateuser = await User.findByIdAndUpdate(req.params.id, {
$set:req.body,
})
res.status(200).json(updateuser)
} catch (error) {
next(error)
}
}
}
how to updating with id of user
req.params.id will be of type string, while req.user.id will be probably of type ObjectId.
Can you try this:
if (req.params.id.toString() === req.user.id.toString()) {
As mentioned before req.user.id type is ObjectId. Also you should send an error when ids are not the same.
Example for your code:
const updateUser = async (req, res, next) => {
try {
if (req.params.id !== req.user.id.toString()) {
// Send error in here.
}
const updateuser = await User.findByIdAndUpdate(req.params.id, {
$set: req.body,
});
res.status(200).json(updateuser);
} catch (error) {
next(error);
}
};
I'm using Facebook chat api to create a simple cli script that will reply to messages that are sent to my facebook account. I'm trying to assign and get the user name and my name to use them inside the reply but they are always undefined. I think that the object property aren't assigned correctly. Is there a fix for this?
require('dotenv').config();
const fs = require('fs');
const fb = require('facebook-chat-api');
const path = require('path');
const appStateFile = path.format({ dir: __dirname, base: 'appstate.json' });
let currentUser = null;
if( !fs.existsSync(appStateFile) ){
//debug .env
console.log(process.env);
fb({email: process.env.FB_EMAIL, password: process.env.FB_PWD}, (err, api) => {
if(err){
return console.log(err);
}
console.log(api);
api.setOptions({
listenEvents: true
});
fs.writeFileSync(appStateFile, JSON.stringify(api.getAppState()));
let id = api.getCurrentUserID();
api.getUserInfo(id, (err, profile) => {
console.log(profile); // profile is logged correctly
currentUser = profile;
});
api.listenMqtt( (err, event) => {
if(err){
return console.log(err);
}
if(event.type === 'message'){
console.log(event.body)
api.getUserInfo(event.senderID, (err, user) => {
if(err){
return console.log(err);
}
console.log(user); // user object is logged correctly
api.sendMessage('...', event.threadID)
});
}
});
});
}else{
fb({appState: JSON.parse(fs.readFileSync(appStateFile))}, (err, api) => {
if(err){
return console.log(err);
}
console.log(api);
api.setOptions({
listenEvents: true
});
let id = api.getCurrentUserID();
api.getUserInfo(id, (err, profile) => {
console.log(profile);
currentUser = profile;
});
api.listenMqtt( (err, event) => {
if(err){
return console.log(err);
}
if(event.type === 'message'){
console.log(event.body)
api.getUserInfo(event.senderID, (err, user) => {
if(err){
return console.log(err);
}
console.log(user)
api.sendMessage(`FB Pager v1.0.\nHi ${user.name}!Your message was forwarded with an email to ${currentUser.name}.`, event.threadID)
});
}
});
});
}
I think the problem here is that api.getUserInfo is asynchronous.
So you would need to nest them to get it to work.
Or you can try this, since getUSerInfo allows you to add an array of user ids to get the data for:
api.listenMqtt((err, event) => {
if (err) {
return console.log(err);
}
if (event.type === "message") {
const currentUserId = api.getCurrentUserID();
const senderId = event.senderID;
api.getUserInfo([currentUserId, senderId], (err, ret) => {
if(err) return console.error(err);
// Ret should contain the two users
// See: https://github.com/Schmavery/facebook-chat-api/blob/master/DOCS.md#getUserInfo
console.log(ret);
});
}
});
Nesting user calls method:
api.listenMqtt((err, event) => {
if (err) {
return console.log(err);
}
if (event.type === "message") {
let currentUserId = api.getCurrentUserID();
api.getUserInfo(currentUserId, (err1, signedInUser) => {
if (err1) {
return console.log(err);
}
api.getUserInfo(event.senderID, (err2, userInMessage) => {
if (err2) {
return console.log(err);
}
console.log(signedInUser, userInMessage)
api.sendMessage("...", event.threadID);
});
});
}
});
After a lot of debug I've found the correct way to access the needed informations. Since the user informations after that are retrived are mapped to another object that is the userId, the only way to access to each property is to use a for loop. Initially I was thinking that this can be avoided but unfortunately it's necessary otherwise using only dot notation will result in undefined. This is how I've solved
api.getUserInfo(userId, (err, user) => {
let username;
if(err){
return console.log(err);
}
for(var prop in user){
username = user[prop].name;
}
api.sendMessage(`Hello ${username!}`, event.threadID);
});
I have a method that deletes products and before it does it check if the user who is trying to delete the product is the user who created it. When i execute it with Insomnia it successfully removes the product but i get an error on the console saying cannot set headers after they are sent to the client.
My method:
exports.deleteProduct = (req, res) => {
const id = req.params.productId;
Product.deleteOne({ _id: id, userId: req.user._id }, () => {
return res.status(401).json("Not authorized");
})
.then(() => {
return res.status(200).json("Product deleted");
})
.catch((err) => {
return res.status(500).json({
error: err,
});
});
};
I'm pretty sure this is happening because I'm chaining a .then() and .catch() after executing it.
I tried to do this but it didn't work because the err parameter that I'm sending to the callback function is null.:
exports.deleteProduct = (req, res) => {
const id = req.params.productId;
Product.deleteOne({ _id: id, userId: req.user._id }, (err) => {
if (err) {
return res.status(401).json("Not authorized");
}
return res.status(200).json("Product deleted");
});
};
When i tried this second approach I always got the 200 status, meanwhile the product didn't delete.
Any idea how to deal with this?
You can try something like this:
Product.deleteOne({ _id: id, userId: req.user._id }, (err, result) => {
if(err) {
return "something"
}
return "something else"
});
or: in async / await way
try {
await Product.deleteOne({ _id: id, userId: req.user._id });
} catch (err) {
// handle error here
}
By the way, why you are passing userId at the deleteOne method?
I'm a newbie in node js Development. I just learn node js in short time ago. Here I create a router file
import express from 'express';
import storyController from '../../controllers/story';
const router = express.Router();
router.post('/', (req, res) => {
const { author, title } = req.body;
console.log(author);
const story = {
author: req.body.author,
title: req.body.title,
content: req.body.content,
tags: req.body.tags
};
storyController.createStory(story, function(error, result){
console.log("halo");
if(error)
res.status(500).send({ success: false, message: error.message});
res.status(200).send({ success: true, message: "Success"});
});
});
Then, i create one more file referred as the controller here
import mongoose from 'mongoose';
const Story = mongoose.model('Story');
exports.createStory = async (story) => {
const { author, title } = story;
if(!author){
console.log("hahaAuthor");
return {
error: true,
message: 'You must write an author name!'
};
}
if(!title) {
console.log("haha");
return {
error: true,
message: 'You must write a title!'
}
}
const newStory = new Story({
author: author,
title: title,
content: story.content,
tags: story.tags,
slug: ''
});
newStory.save().then((story) => {
return { error: false, result: story};
}).catch((error) => {
return { error: error};
})
};
But, unfortunately I don't know why my function in router file doesn't call the callback function. The console.log doesn't even called yet. Please help. Otherwise, maybe you have a better way to do this. Thanks!
As createStory is an async function. Change your code like this. You are mixing async with Promise and callback
exports.createStory = async (story) => {
...
// Change the promise to await
let story = await newStory.save();
return { error: false, result: story};
};
Error should be handled in the controller with Promise catch clause.
Something like
router.post('/', (req, res) => {
storyController.createStory.then(data => {
return res.json({error: false, data: data});
}).catch(e => {
return res.json({error: true});
})
});
Note: Either use callback or async. async is the best option now adays
May be this can work:
// 1. callback style
newStory.save().then((story) => {
return cb(null, story);
}).catch((error) => {
return cb(error);
})
// 2. await
await newStory.save();
// controller
router.post('/', (req, res) => {
storyController.createStory.then(data => {
return res.json(...);
}).catch(e => {
return res.json(...);
});
If you use callback style, Error-First Callback is better.
I have created an api using nodejs, express and mongodb. I am fetching data now without sending any query. But in my frontend I have an input where the user can search for a recipe. So for example if a user types "Today" i should get response related to today only. How to check that in db and retrieve data?
module.exports = function(app, db) {
app.get("/dates/", (req, res) => {
db
.collection("dates")
.find()
.toArray((err, item) => {
if (err) {
res.send({ error: "An error has occured" });
} else {
res.send(item);
}
});
});
While making the api call , pass the dish as query parameter
For example '/recipes/?dish="Pizza" '
and in the express use the following.
module.exports = function(app, db) {
app.get("/recipes/", (req, res) => {
let queryDish = req.query.dish; // assuming /recipes/?dish="Pizza"
let query = { 'title' : { '$regex' : queryDish, '$options' : 'i' } };
db
.collection("recipes")
.find(query)
.toArray((err, item) => {
if (err) {
res.send({ error: "An error has occured" });
} else {
res.send(item);
}
});
});