Postman sending request hanging - mongodb

I am new to Postman. I am unsure of why my postman is hanging when trying to get from "http://localhost:8001/application/cards". It's supposed to respond with an empty array but it just keeps sending request. It works for "http://localhost:8001" to which it does give me "Hello World!" but doesn't work when I add /application/cards. Is there new syntax update? I can give more information about my code if necessary.
...
const app = express();
const port = process.env.PORT || 8001;
...
app.use(express.json());
app.use(Cors());
mongoose.connect(connection_url, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
});
app.get('/', (req, res) => res.status(200).send('Hello World!'));
app.post('/application/cards', (req, res) => {
const dbapplication = req.body;
Cards.create(dbapplication, (err, data) => {
if (err)
{
res.status(500).send(err);
}
else
{
res.status(201).send(data);
}
});
});
app.get('/application/cards', (req, res) => {
Cards.find((err, data) => {
if (err)
{
res.status(500).send(err);
}
else
{
res.status(200).send(data);
}
});
});
Note: /application/cards in my question was an example, but SpartanSwipe is actually my application.
Upon testing data using POST http://localhost:8001/application/cards, I got a 500 Internal Server Error after about 10 seconds.
[
{
"name": "Test Name",
"profPic": "https://as1.ftcdn.net/v2/jpg/01/17/42/38/500_F_117423860_bApe5ResfiVkO0G0UlUjUVNpAtFUWYYy.jpg"
},
{
"name": "Nest Tame",
"profPic": "https://thumbs.dreamstime.com/z/happy-university-college-student-thumbs-up-15010463.jpg"
}
]
Here is my database .js for the cards
import mongoose from 'mongoose';
const cardSchema = mongoose.Schema({
name: String,
profPic: String
});
export default mongoose.model('cards', cardSchema);

Assuming your DB Connection is ok?? I think your issue lies in the structure of your code. According to the mongoose documentation, your first parameter should be an empty object followed by the callback to return all records like the example given below.
Cards.find((err, data) => {
if (err)
{
res.status(500).send(err);
}
else
{
res.status(200).send(data);
}
});
Example
Cards.find({}, (err, docs) => {
if (err) {
res.status(500).send(err);
}
res.status(200).send(docs);
});

Related

Mongoose pre save middleware is not triggering/saving hashed passwords to db

I am trying to pre save and hash password with bcrypt in mongoose in my next.js project, but password still unhashed. i tryed every link in stackoverflow and didnt solve it, the password still saved unHashed.
mongoose version: 6.9.1
this is my users.model file:
import {
models,
model,
Schema,
} from 'mongoose';
import bcrypt from 'bcrypt';
const UserSchema: Schema = new Schema({
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
displayName: {
type: String,
required: true,
},
role: {
type: String,
},
});
UserSchema.pre('save', function (next) {
console.log('Pre-Save Hash has fired.');
let user = this;
bcrypt.genSalt(10, (err, salt) => {
if (err) console.error(err);
bcrypt.hash(user.password, salt, (err, hash) => {
user.password = hash;
next();
});
});
});
const UserModel = models.Users || model('Users', UserSchema, 'users');
export default UserModel;
this is my adding function file:
import dbConnect from '#/utils/mongodb';
import UserModel from '#/models/user.model';
import { NextApiRequest, NextApiResponse } from 'next';
import { MongoError } from 'mongodb';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// const { email, password } = req.query;
try {
dbConnect();
const query = req.body;
const newUser = new UserModel(query);
const addedUser= await newUser.save(function (err: MongoError) {
if (err) {
throw err;
}
});
res.status(200).json(addedUser);
} catch (error) {
console.error(error);
res.status(500).json({ message: 'Internal server error' });
}
}
i cant see the 'Pre-Save Hash has fired.' in my console also..
// You need to add user.isModified("password")
userSchema.pre("save", function (next) {
var user = this;
if (user.isModified("password")) {
bcrypt.genSalt(SALT_I, (err, salt) => {
if (err) {
return next(err);
}
bcrypt.hash(user.password, salt, (err, hash) => {
if (err) {
return next(err);
}
user.password = hash;
next();
});
});
} else {
next();
}
});
userSchema.methods.comparePassword = function (candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, (err, isMatch) => {
if (err) return cb(err);
cb(null, isMatch);
});
};
// to make register end point
import mongoose from "mongoose";
import User from "../../../models/User";
const dbConnect = async () => {
mongoose
.connect("mongodb://localhost:27017/test")
.then(() => {
console.log("Connected to mongoDb");
})
.catch((error) => {
console.log(error);
});
};
export default async function handler(req, res) {
try {
await dbConnect();
const query = req.body;
const newUser = new User(query);
await newUser.save(function (err, result) {
if (err) {
throw err;
} else {
res.status(200).json(result);
}
});
} catch (error) {
console.error(error);
res.status(500).json({ message: "Internal server error" });
}
}
thanks to all.
The problem was in my dbconnect file!

Is there an easier way to post an element in the html-post method?

const express = require("express");
const cors = require("cors");
const dotenv = require("dotenv");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
dotenv.config();
app.use(cors());
app.use(bodyParser.json());
const { Schema } = mongoose;
const userSchema = Schema({
imageUrl: { type: String },
description: { type: String },
title: { type: String },
price: { type: Number },
});
const Users = mongoose.model("users", userSchema);
app.get("/", (req, res) => {
res.send("started");
});
`get metod`
app.get("/users", (req, res) => {
Users.find({}, (err, docs) => {
if (!err) {
res.send(docs);
} else {
res.status(404).json({ message: err });
}
});
});
app.get("/users/:id", (req, res) => {
const { id } = req.params;
Users.findById(id, (err, doc) => {
if (!err) {
if (doc) {
res.send(doc);
}
} else {
res.status(404).json({ message: err });
}
});
});
`delete metod`
app.delete("/users/:id", (req, res) => {
const { id } = req.params;
Users.findByIdAndDelete(id, (err, doc) => {
if (!err) {
res.send("Succesfully deleted");
} else {
res.status(404).json({ message: err });
}
});
});
`post metod`
app.post("/users", (req, res) => {
const obj = {
imageUrl: req.body.imageUrl,
description: req.body.description,
title: req.body.title,
price: req.body.price,
};
console.log(obj);
let user = new Users(obj);
user.save();
res.send({ message: " Succesfully added" });
});
const PORT = process.env.PORT;
const url = process.env.URL.replace("<password>", process.env.PASSWORD);
mongoose.set("strictQuery", true);
mongoose.connect(url, (err) => {
if (!err) {
console.log("DB connected");
app.listen(PORT, () => {
console.log("Server start");
});
}
});
I'm trying to learn how exactly get post delete queries work
I'm trying to reduce the code here, but no matter what I do, small errors appear in the end. I have a json string, I want to pass it to POST method. But the 'execute', and 'executeMethod ' are throwing error as below:
"The method execute(HttpUriRequest) in the type HttpClient is not applicable for the arguments (PostMethod)". i have included the depencencies.

How to create new item in collection if not exists, otherwise, update price and quantity when added to cart

Hi iam new to Vue and trying too build a MEVN application. What iam trying to do is when user adds item in cart it should store one document in mongoDB and if user adds more of same item only the price and quantity for the document should increase and not create new document.
Here is code for client when user adds item in cart,iam using Vue3:
async addToCart(state, product) {
console.log(state);
let dbProducts = await axios
.get(`http://localhost:1337/items/`)
.then((res) => res.data)
.catch((error) => console.log(error));
let item = dbProducts.find((i) => i.id === product.id);
console.log(item);
console.log('addTOcart');
if (item) {
console.log('put request');
item.quantity++;
console.log('quantity', item.quantity);
axios
//.put(`http://localhost:1337/items/${uniqueId}`, item)
.put(`http://localhost:1337/items/`, item)
.then((res) => {
console.log(res.data);
alert(res.data);
})
.catch((error) => console.log(error));
} else {
product = { ...product, quantity: 1 };
state.cart.push(product);
axios.post('http://localhost:1337/items', {
id: product.id,
title: product.title,
price: product.price,
quantity: product.quantity,
shortDesc: product.shortDesc,
category: product.category,
longDesc: product.longDesc,
imgFile: product.imgFile,
serial: product.serial,
});
}
},
And here is code for the server, iam using express js:
const express = require('express');
const app = express();
const Items = require('./Items');
const connection = require('./connection');
const Port = process.env.Port || 1337;
const cors = require('cors');
app.use(cors());
connection();
app.use(express.json());
app.post('/items', (req, res) => {
const data = new Items(req.body);
data
.save()
.then((Items) => {
console.log('item saved', Items);
res.json({ succcess: true, Items });
})
.catch((err) => {
console.log(err);
});
});
app.get('/items', async (req, res) => {
Items.find({}, (err, items) => {
res.json(items);
});
});
app.put('/items', function (req, res) {
console.log(req.body);
//Items.updateOne({ _id: req.body._id }, req.body);
Items.findOneAndUpdate({ _id: req.body._id }, req.body);
// Items.findOne({ _id: req.body._id });
});
app.listen(Port, () => {
console.log(`App running on port ${Port}`);
});
As #HeikoTheißen suggested, you should handle the logic of the operation on the server, using a single POST request:
const express = require('express');
const app = express();
const Items = require('./Items');
const connection = require('./connection');
const Port = process.env.Port || 1337;
const cors = require('cors');
app.use(cors());
connection();
app.use(express.json());
app.post('/items', async (req, res) => {
try {
let item = await Items.findById(req.body.id);
if (!item) {
item = await Items.create(req.body);
} else {
item.quantity++;
await item.save();
}
res.json({ succcess: true, item });
} catch (err) {
res.json({ succcess: false });
}
});
app.listen(Port, () => {
console.log(`App running on port ${Port}`);
});
You should simplify your client code as:
async function addToCart(state, product) {
try {
const { data } = await axios.post('http://localhost:1337/items', product);
// Add new product to card if necessary
if (!state.cart.some((p) => p.id === data.item.id)) {
state.cart.push(data.item);
}
} catch (err) {
console.log(err);
}
}

why an empty array when I do an app.get()?

So I have a mongodb database to which I have imported some json data to its collection.
When I do a db.posts.find(), the data imported successfully, but when I attempt a get request, I get an empty array [].
Here is my server.js file:
'use strict';
const express = require('express');
const morgan = require('morgan');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const { DATABASE_URL, PORT } = require('./config');
const { BlogPost } = require('./models');
const app = express();
app.use(morgan('common'));
app.use(express.json());
app.get('/posts', (req, res) => {
BlogPost
.find()
.then(posts => {
res.json(posts.map(post => post.serialize()));
})
.catch(err => {
console.error(err);
res.status(500).json({ error: 'something went terribly wrong' });
});
});
app.get('/posts/:id', (req, res) => {
BlogPost
.findById(req.params.id)
.then(post => res.json(post.serialize()))
.catch(err => {
console.error(err);
res.status(500).json({ error: 'something went horribly awry' });
});
});
app.post('/posts', (req, res) => {
const requiredFields = ['title', 'content', 'author'];
for (let i = 0; i < requiredFields.length; i++) {
const field = requiredFields[i];
if (!(field in req.body)) {
const message = `Missing \`${field}\` in request body`;
console.error(message);
return res.status(400).send(message);
}
}
BlogPost
.create({
title: req.body.title,
content: req.body.content,
author: req.body.author
})
.then(blogPost => res.status(201).json(blogPost.serialize()))
.catch(err => {
console.error(err);
res.status(500).json({ error: 'Something went wrong' });
});
});
app.delete('/posts/:id', (req, res) => {
BlogPost
.findByIdAndRemove(req.params.id)
.then(() => {
res.status(204).json({ message: 'success' });
})
.catch(err => {
console.error(err);
res.status(500).json({ error: 'something went terribly wrong' });
});
});
app.put('/posts/:id', (req, res) => {
if (!(req.params.id && req.body.id && req.params.id === req.body.id)) {
res.status(400).json({
error: 'Request path id and request body id values must match'
});
}
const updated = {};
const updateableFields = ['title', 'content', 'author'];
updateableFields.forEach(field => {
if (field in req.body) {
updated[field] = req.body[field];
}
});
BlogPost
.findByIdAndUpdate(req.params.id, { $set: updated }, { new: true })
.then(updatedPost => res.status(204).end())
.catch(err => res.status(500).json({ message: 'Something went wrong' }));
});
app.delete('/:id', (req, res) => {
BlogPost
.findByIdAndRemove(req.params.id)
.then(() => {
console.log(`Deleted blog post with id \`${req.params.id}\``);
res.status(204).end();
});
});
app.use('*', function (req, res) {
res.status(404).json({ message: 'Yo stupido, Not Found' });
});
// closeServer needs access to a server object, but that only
// gets created when `runServer` runs, so we declare `server` here
// and then assign a value to it in run
let server;
// this function connects to our database, then starts the server
function runServer(databaseUrl, port = PORT) {
return new Promise((resolve, reject) => {
mongoose.connect(databaseUrl, err => {
if (err) {
return reject(err);
}
server = app.listen(port, () => {
console.log(`Your app is listening on port ${port}`);
resolve();
})
.on('error', err => {
mongoose.disconnect();
reject(err);
});
});
});
}
// this function closes the server, and returns a promise. we'll
// use it in our integration tests later.
function closeServer() {
return mongoose.disconnect().then(() => {
return new Promise((resolve, reject) => {
console.log('Closing server');
server.close(err => {
if (err) {
return reject(err);
}
resolve();
});
});
});
}
// if server.js is called directly (aka, with `node server.js`), this block
// runs. but we also export the runServer command so other code (for instance, test code) can start the server as needed.
if (require.main === module) {
runServer(DATABASE_URL).catch(err => console.error(err));
}
module.exports = { runServer, app, closeServer };
and here is my config.js file:
'use strict';
exports.DATABASE_URL =
process.env.DATABASE_URL || 'mongodb://localhost/seed_data';
exports.PORT = process.env.PORT || 8080;
In my models.js file, this is what my mongoose model looks like:
'use strict';
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const blogPostSchema = mongoose.Schema({
author: {
firstName: String,
lastName: String
},
title: {type: String, required: true},
content: {type: String},
created: {type: Date, default: Date.now}
});
blogPostSchema.virtual('authorName').get(function() {
return `${this.author.firstName} ${this.author.lastName}`.trim();
});
blogPostSchema.methods.serialize = function() {
return {
id: this._id,
author: this.authorName,
content: this.content,
title: this.title,
created: this.created
};
};
const BlogPost = mongoose.model('BlogPost', blogPostSchema);
module.exports = {BlogPost};
The issue is with your first parameter in your mongoose.model(). Since you shared that the collection name is posts, that should be the name of your first parameter as a string 'posts'.
Checkout this documentation on how to declare collection name and model name:
How to declare collection name and model name in mongoose
So your mongoose.model() should look like this:
const BlogPost = mongoose.model('posts', blogPostSchema);
Give that a try.

MongoDB query won't return object in my Express API (React)

I have done this so many times before, but I can't seem to find the issue, it's probably something small and stupid. Take a look at the /server.js file here! (Shortened for demonstration purposes)
/* Make Mongoose promise based */
mongoose.Promise = Promise;
mongoose.connect('mongodb://localhost:27017', options);
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error: '));
/* Routes */
app.route('/games')
.post(postGame)
.get(getGames);
app.route('/games/:id')
.get(getGame)
.delete(deleteGame);
app.route("*").get((req, res) => {
res.sendFile('client/dist/index.html', { root: __dirname });
});
const port = 8080;
app.listen(port, () => {
console.log(`Connected! Server listening on port: ${port}`);
});
Then for my Game model, I have that in app/models/game.js.
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
const gameSchema = new Schema(
{
name: {
type: String,
required:true
},
year: {
type: Number,
required:true
},
description: {
type: String,
required:true
},
picture: {
type: String,
required:true
},
postDate : { type: Date, default: Date.now }
}
);
export default mongoose.model('Game', gameSchema);
This is where I believe I am having the issue.
/* Import Game model schema */
import Game from '../models/game';
const getGames = (req, res) => {
Game.find({}, (err, games) => {
console.log(err, games)
if (err) {
res.send(err);
}
res.json(games);
});
}
const getGame = (req, res) => {
const { id } = req.params;
Game.findById(id, (err, game) => {
if (err) {
res.send(err);
}
res.json(game);
});
}
const postGame = (req, res) => {
let game = Object.assign(new Game(), req.body);
game.save(err => {
if (err) {
res.send(err);
}
res.json({ message: 'Game successfully created!' });
});
};
const deleteGame = (req, res) => {
Game.remove(
{ _id: req.params.id },
err => {
if (err) {
res.send(err);
}
res.json({ message: 'Game successfully deleted!' });
}
);
};
export {
getGames,
getGame,
postGame,
deleteGame
};
Just do be clear... I went into the mongo shell.
I did...
connecting to: test
> db.createCollection('Game')
> db.Game.insert({name: "SSB", year: 2001, description: "Fun Game", picture: "http://google.com", postDate: "2017-01-03T08:51:45.888Z"});
And when I type > db.Game.find({}); I am returned with exactly what I have...
{
"_id" : ObjectId("58c2223e32daa04353e35bdc"),
"name" : "SSB",
"year" : 2001,
"description" : "Fun Game",
"picture" : "http://google.com",
"postDate" : "2017-01-03T08:51:45.888Z"
}
You see when I go to http://localhost:8080/games I am returned with an empty JSON and I just wanna know why. I am 70% sure, it is because it isn't connected to the right collection but I don't remember how to test that :(
I wanted to make this a comment but it won't let me because I don't have a 50 reputation, but I believe I found the issue.
const getGame = (req, res) => {
const { id } = req.params;
Game.findById(id, (err, game) => {
if (err) {
res.send(err);
}
res.json(game);
});
}
In this piece of code you are setting the id to req.params, but you need to set it to req.params.id which is what you passed in your route.
Should look like this:
const {id} = req.params.id;
If you logged id, you would probably get an object that says:
{ id: "[whatever_id_you_put_here]" }
however if you log req.params.id you should get the correct id you put in that spot..
The reason you're getting [] is because you're actually connected to the database and you are actually trying to "get" something, but that something doesn't exist so it sends an empty response.
I hope this helps..