getting internal Server error and empty Object - node.js

made an API for Social media Application to get timeline posts on the app, I requested from Thunder Client
request query is like: http://localhost:8000/post/63d4051a252ef6c3d50d7f17/timeline, where userId is this :63d4051a252ef6c3d50d7f17,
i did log userId and correctly got Data Document from mongoDB
try {
const currentUserPost = await PostModel.find({ userId: userId });
console.log( currentUserPost )
}
but still getting empty object {} error is: Internal server error status code 500 on thunder client,
check out once below code, and let me know what's wrong and why. it seems good to me but it isn't working.
PostControler.js
const PostModel = require("../Models/Postmodels");
const mongoose = require("mongoose");
const UserModel = require("../Models/Usermodel");
/ get timeLine post
const getTimeLinePost = async (req, res) => {
const userId = req.params.id;
try {
const currentUserPost = await PostModel.find({ userId: userId });
console.log( currentUserPost )
const followingPost = await UserModel.aggregate([
{
$match: {
_id: new mongoose.Types.ObjectId(userId),
}
},
{
$lookup: {
from: "posts",
localField: "following",
foreignField: "userId",
as: "followingPosts",
}
},
{
$project: {
followingPost: 1,
_id: 0,
}
},
]);
res.status(200).json(currentUserPost.concat(...followingPost[0].followingPost)
.sort((a,b)=>{
return b.createdAt - a.createdAt
}));
} catch (error) {
res.status(500).send(error);
}
};
module.exports = { createPost,getPost, updatePost, deletePost, likesDislikesPost, getTimeLinePost };
PostRoute.js
const express = require("express");
const {createPost,getPost, updatePost, deletePost, likesDislikesPost, getTimeLinePost} = require("../Controller/PostControler");
const router = express.Router();
router.post('/', createPost)
router.get('/:id', getPost)
router.put('/:id', updatePost)
router.delete('/:id', deletePost)
router.put('/:id/like', likesDislikesPost)
router.get('/:id/timeline', getTimeLinePost)
module.exports = router
index.js
const express = require("express")
require('dotenv').config()
const bodyparser = require("body-parser")
const mongoose = require("mongoose")
const app = express();
const Authroute = require("./Routes/Authroute")
const UserRoute = require("./Routes/userRout")
const PostRout = require("./Routes/PostRoute")
.
.
.
.
.
.
app.use("/auth",Authroute)
app.use("/user",UserRoute)
app.use("/post", PostRout)

Related

POST going directly to the catch error and not saving data using mongoose, MongoDB, NodeJS, and Express

I already tried some possible solutions and even created and wrote the code again but I am still getting errors. I have created a diminute version of my whole code which connects to the database using Mongoose but after the Schema is created and I import the model in places-controllers my data that I write in POSTMAN goes directly to:
FYI: In this case I want POST request from createPlace to properly work.
Data entry: URL: http://localhost:5000/api/places/
{
"title": "Punta Arena Stfdsfdsfsdfop",
"description": "One stop Stop. Does not have tr12affic lights.",
"busrespect": "12ysdfdsfsfes",
"address": "Avenida Solunna",
"creator": "52peru soiflsdjf36"
}
OUTPUT:
{
"status": "error caught"
}
which is what I told the program to define if the try did not work.
IN app.js I have the following code:
const express= require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const placesRoutes = require("./routes/places-routes");
const HttpError = require ("./models/http-error");
const app = express();
app.use(bodyParser.json());
app.use('/api/places', placesRoutes);
app.use((req, res, next) => {
const error= new HttpError('Route not available. Try something different?', 404);
throw error;
});
app.use((error, req, res, next) =>{
if (res.headerSent) {
return next(error);
}
res.status(error.code || 500)
res.json({message: error.message || "An unknown error occured! Sorry" });
});
url = '<mongo_url>'
mongoose.connect(url, {useNewUrlParser: true}).then(()=>{
console.log("Connected to database")
app.listen(5000);
}).catch(erro => {
console.log(erro)
});
In places-routes.js I have the following code:
const express = require('express');
const {check} = require('express-validator')
const placesControllers=require('../controllers/places-controllers');
const router = express.Router();
router.get('/:pid', placesControllers.getPlaceById );
router.get('/user/:uid',placesControllers.getPlacesByCreatorId );
router.post('/' ,[
check('title')
.not()
.isEmpty(),
check('description').isLength({ min: 5 }),
check('address')
.not()
.isEmpty()
],
placesControllers.createPlace);
router.patch('/:pid', [
check('title')
.not()
.isEmpty(),
check('description').isLength({ min: 5 })
] , placesControllers.updatePlace );
router.delete('/:pid', placesControllers.deletePlace);
module.exports=router;
In places-controllers.js I have the following code:
const HttpError = require('../models/http-error');
const { validationResult } = require('express-validator');
//const getCoordsForAddress= require('../util/location');
const BusStop = require('../models/place');
let INITIAL_DATA = [
{
id: "p1",
title: "Samoa Stop",
description: "My first bus stop in Lima",
//location: {
// lat: 40.1382,
// lng:-23.23
// },
address: "Av. La Molina interseccion con calle Samoa",
busrespect: "yes",
creator: "u1"
}
];
const getPlaceById = (req, res, next) => {
const placeId = req.params.pid // Accessing the p1 in pid URL scrapping {pid:'p1'}
const place= INITIAL_DATA.find(p => { //find method goes over each element in the array, the argument p represents the element where find loop is
return p.id ===placeId
});
if (!place) {
const error= new HttpError('No bus stop found for the provided ID.', 404);
throw error;
}
res.json({place: place});
};
const getPlacesByCreatorId = (req, res, next)=> {
const userId = req.params.uid;
const places = INITIAL_DATA.filter(p=>{ //filter to retrieve multiple places, not only the first one
return p.creator ===userId;
});
if (!places || places.length===0) {
return next(
new HttpError('Could not find bus stops for the provide user id', 404)
);
}
res.json({places});
};
const createPlace = async (req, res,next) => {
const errors = validationResult(req);
if (!errors.isEmpty()){
return next(new HttpError ('Invalid bus stop please check your data', 422));
}
//const { title, description, busrespect, address, creator } = req.body; //erased location for now.
/* let place = new BusStop({
title: req.body.title,
description: req.body.description,
busrespect: req.body.busrespect,
address : req.body.address,
creator: req.body.creator
})
awaitplace.save()
.then(response=>{
res.json({
message : "Employee added sucessfully!"
})
})
.catch(err=>{
res.json({
message : "An error has occured!"
})
})
} */
const { title, description, busrespect, address, creator } = req.body;
try {
await BusStop.create({
title:title,
description: description,
busrespect:busrespect,
address: address,
creator: creator
});
res.send({status: "ok"});
} catch(error) {
res.send({status:"error caught"});
}
};
const updatePlace = (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()){
console.log(errors);
throw new HttpError ("Invalid inputs passed, please check your data ", 422);
};
const { title, description } = req.body;
const placeId = req.params.pid;
const updatedPlace = { ...INITIAL_DATA.find(p => p.id === placeId)};
const placeIndex = INITIAL_DATA.findIndex(p => p.id === placeId);
updatedPlace.title = title;
updatedPlace.description = description;
INITIAL_DATA[placeIndex] = updatedPlace;
res.status(200).json({place: updatedPlace});
};
const deletePlace = (req, res, next) => {
const placeId = req.params.pid;
if (!INITIAL_DATA.find(p=> p.id ===placesId))
throw new HttpError('Could not find a bus stop for that ID ')
INITIAL_DATA = INITIAL_DATA.filter(p=> p.id !== placeId)
res.status(200).json({message: 'Deleted Place'});
};
exports.getPlaceById= getPlaceById;
exports.getPlacesByCreatorId = getPlacesByCreatorId;
exports.createPlace = createPlace;
exports.updatePlace = updatePlace;
exports.deletePlace = deletePlace;
Inside models folder I have two files: http-error.js which has this code:
class HttpError extends Error {
constructor(message, errorCode) {
super (message);
this.code = errorCode;
}
}
module.exports = HttpError;
The other file inside is the schema which is place.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const placeSchema = new Schema({
title: {
type: String
},
description: {
type: String
},
address: {
type: String
},
busrespect: {
type: String
},
creator: {
type: String
}
},
)
const BusStop = mongoose.model('BusStop', placeSchema)
module.exports= BusStop
Summary: somewhere in the try catch part from createPlace something is going wrong since my data entry is always going to the error status I indicated in that part.

Req.body not fetching array value from schema when save data using node

When I'm saving the data using node in my MongoDB schema array would be empty here my code and output could you please explain why this error happening
controller.js
const {name,age,social,songs}=new musicModel(req.body)
const addMusic =await musicModel.create({
name,age,songs,social
})
if (addMusic) {
res.send(addMusic)
} else {
res.status(500).send("unsuccessfull.")
}
}
Here's my schema but it will perfectly work when I send response using postmen but when I saved this the bellow array was undefined or null
model.js
const mongoose = require("mongoose")
const songSchema= mongoose.Schema({
title:{
type:String
},
sales:{
type:String
}
})
const musicSchema = mongoose.Schema({
name: {
type: String
},
age: {
type: String
},
social: {
show: {
type: Number
}, tours: {
type: Number
},
},songs:[songSchema]
})
const musicModel =mongoose.model("Music",musicSchema)
module.exports= musicModel
app.js
const express = require('express')
const logger = require('morgan')
const bodyParser = require('body-parser')
const mongoose = require('mongoose')
require("dotenv/config")
const cors = require('./middleware/cors')
const productsRouter = require('./routes/products')
const customerRouter= require('./routes/customers')
const quotRouter=require('./routes/quots')
const usersRouter = require('./routes/users')
mongoose.connect(
process.env.CONNECTION_URL,
{ useNewUrlParser: true },
(err) => {
if (!err) {
console.log('DB Connected')
}
}
);
const app = express()
app.use(express.static('public'))
app.use(logger('dev'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended:true}))
app.use(cors)
app.use('/products', productsRouter)
app.use('/customer',customerRouter)
app.use('/', usersRouter)
app.use('/quotation',quotRouter)
module.exports =app;
output
{
"name": "ashit",
"age": "67",
"social": {
"show": 566,
"tours": 47
},
"songs": [],
"_id": "61c57a22a6903d467834d19f",
"__v": 0
}
You have the choice between theses two types of code :
First Solution :
const {name,age,social,songs}=req.body
const addMusic =await musicModel.create({
name,age,songs,social
})
if (addMusic) {
res.send(addMusic)
} else {
res.status(500).send("unsuccessfull.")
}
}
Second solution :
const {name,age,social,songs}=new musicModel(req.body)
const addMusic =await musicModel.save()
if (addMusic) {
res.send(addMusic)
} else {
res.status(500).send("unsuccessfull.")
}
}
Try to do like this:
Declare the songModel and export it as well:
const songSchema= mongoose.Schema({
title:{
type:String
},
sales:{
type:String
}
})
const songModel =mongoose.model("Song",songSchema)
...
module.exports= { musicModel, songModel }
Change the songs attribute in the musicSchema to be a reference:
songs:[
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Song',
}
]
After creating the new song, create each song object as well and add its reference to the musicModel object:
const { name, age, social, songs } = req.body;
const addMusic = await musicModel.create({
name,
age,
social,
});
songs.forEach((song) => {
const newSong = await songModel.create(song);
addMusic.songs.push(newSong._id);
});
await addMusic.save();
if (addMusic) {
res.send(addMusic);
} else {
res.status(500).send("unsuccessfull.");
}

How do I reference documents from other collection in express

I have 2 collections here >>course & author
I need to prepare my course schema in such a way that it references the author and at the post request I only need to put the id.I am using #joi13 This is what I have done so far.
course schema
const mongoose = require('mongoose')
const Joi = require('joi')
Joi.objectId= require('joi-objectid')(Joi)
// schema
const courseSchema = new mongoose.Schema({
...
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Author'
}
})
// the model
const Course = mongoose.model('Courses', courseSchema)
// validation
const courseValidation = (course) => {
const schema = {
...
authorId: Joi.objectId().required()
}
return Joi.validate(course, schema)
}
the course router
const {Course, validate} = require('../models/course')
const express = require('express')
const router = express.Router()
const {Author} = require('../models/author')
// post
router.post('/', async (req, res) => {
const {error} = validate(req.body)
if (error) return res.status(400).send(error.details[0].message)
const title = await Course.findOne({title : req.body.title})
if (title) return res.status(400).send('That user exists')
const author = await Author.find()
if (!author) return res.status(404).send('No such Author')
let course = new Course({
...
author: {
_id: author._id,
username: author.username
}
})
try {
course = await course.save()
res.send(course)
}
catch(er){
console.log(er)
}
})
The error
At line, const author = await Author.find() will return array of authors
while creating course at following lines of you are using author._id which will be undefined, So you have to find a specific Author using findOne (return a single author as object) or you have to use an indexed element of an author like author[0]._id
let course = new Course({
...
author: {
_id: author._id,
username: author.username
}
})

Socket hang up when using axios

I'm having an error "Error: socket hang up" and I don't know what causes this but it saves the data in database.
here's my code:
dataschema.js
const mongoose = require("mongoose");
const DataSchema = new mongoose.Schema({
data1: {
type: String
},
data2: {
type: String
},
data3: {
type: String
},
data4: {
type: String
},
});
const DataModel = mongoose.model("TEST123", DataSchema);
module.exports = DataModel;
routes.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const DataModel = require('./models/dataschema');
var bodyParser = require('body-parser');
app.use(bodyParser.json());
mongoose.connect(
"mongodb://localhost:27017/stocksmonitor?readPreference=primary&appname=MongoDB%20Compass%20Community&ssl=false",
{ useNewUrlParser: true }
);
app.post('/insert', (req, res) => {
const stock = new DataModel({
data1: req.body[0],
data2: req.body[1],
data3: req.body[2],
data4: req.body[3],
})
stock.save();
})
app.listen(3001, () => {
console.log("You are connected");
})
savedata.js
const axios = require('axios');
SaveInfo = () => {
const testdata = ["a", "b", "c", "d"]
axios({
method: 'post',
url: 'http://localhost:3001/insert',
data: testdata
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
SaveInfo();
I inspected the code and found that you did not return response for your controller. In the code below after the save add res.send() or res.json(). So express can return a proper response. Otherwise request will timed out, because it did not resolve and Express will cut the connection. Therefore axios is throwing Error: Socket hang up unexpectedly.
app.post('/insert', (req, res) => {
const stock = new DataModel({
data1: req.body[0],
data2: req.body[1],
data3: req.body[2],
data4: req.body[3],
})
stock.save();
})

Having trouble saving to mongoDB using node

I'm attempting to save data from an API response and keep getting an empty object. I placed a console.log in my code and it shows that I'm getting a response from the api. I seem to be missing something after the fetch request.
From index.js:
const express = require('express')
const bodyParser = require('body-parser')
const path = require('path')
const fetch = require('node-fetch')
const exphbs = require('express-handlebars')
const db = require('./src/models/movie')
require('./src/db/mongoose')
const Movie = require('./src/models/movie')
const app = express()
const port = process.env.PORT || 3000
// APP CONFIG
app.use(express.json())
app.use(bodyParser.urlencoded({extended: true}))
// ROUTES - ADD
app.post('/movies/:imdbID', (req, res) => {
const imdb = req.params.imdbID
const url = `**api link and key**${imdb}`
const movie = fetch(url).then((res) => {
return res.json()
}).then((response) => {
console.log(response)
const addMovie = new Movie(response)
db.Movie.create(addMovie, (err, newMovie) => {
if(err){
res.render('movie404')
} else {
res.redirect('/')
}
})
}).catch((e) => {
res.status(500).send(e)
})
})
From mongoose.js:
const mongoose = require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/movietime-api', {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false
})
From details.handlebars:
<h2>{{details.Title}}</h2>
<img src="{{details.Poster}}" alt="{{details.Title}}">
<p><em>{{details.Plot}}</em></p>
<p>Starring: {{details.Actors}}</p>
<p>Director: {{details.Director}}</p>
<form action="/movies/{{details.imdbID}}" method="POST">
<button type="submit">Add</button>
</form>
From movie.js:
const mongoose = require("mongoose");
// MONGOOSE/MODEL CONFIG
const Movie = mongoose.model('Movie',{
imdbID: String,
Title: String,
Poster: String,
Director: String,
Year: String,
Plot: String,
Ratings: String,
Rated: String,
Genre: String,
Writer: String,
Actors: String
});
module.exports = Movie;
I would expect a redirect to the index page then a new database entry using the above model.
you are almost there just few thing needs to be taken care of:
app.post('/movies/:imdbID', (req, res) => {
const imdb = req.params.imdbID
const url = `**api link and key**${imdb}`
const movie = fetch(url).then((res) => {
return res.json()
}).then((response) => {
console.log(response)
const addMovie = new Movie(response)
addMovie.save((err, newMovie) => {
if(err){
res.render('movie404',newMovie) // to render the details
} else {
res.redirect('/')
}
})
}).catch((e) => {
res.status(500).send(e)
ref

Resources