I'm using postman to make a request to my node.js API, to which I'm using my orders route to send a request following my order controller. Whatever requisition I make using my orders route my requisition hangs and instead of receiving either a 400 or a 500 response, my postman gets stuck on loading screen and it times out after some time. I tried alternatively using the google chrome extension, same results. After the requisition is unsuccessful I receive the following message
I was wondering if it has something to do with how I did the routing in my backend, but I am unsure of this. Hence, here's my code:
model.js:
'use strict';
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const schema = new Schema({
customer: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Customer'
},
number: {
type: String,
required: true
},
createDate: {
type: Date,
required: true,
default: Date.now
},
status: {
type: String,
required: true,
enum: ['created', 'done'],
default: 'created'
},
items: [{
quantity: {
type: Number,
required: true,
default: 1
},
price: {
type: Number,
required: true
},
product: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Product'
}
}],
});
module.exports = mongoose.model('Order', schema);
post method in my order-controller.js:
exports.post = async(req, res, next) => {
try {
const token = req.body.token || req.query.token || req.headers['x-access-token'];
const data = await authService.decodeToken(token);
await repository.create({
customer: data.id,
number: guid.raw().substring(0, 6),
items: req.body.items
});
res.status(201).send({
message: 'Order registered with success!'
});
} catch (e) {
console.log(e);
res.status(500).send({
message: 'Fail to process your requisition'
});
}
};
order-repository.js:
'use strict';
const mongoose = require('mongoose');
const Order = mongoose.model('Order');
exports.get = async(data) => {
var res = await Order
.find({}, 'number status customer items')
.populate('customer', 'name')
.populate('items.product', 'title');
return res;
}
exports.create = async(data) => {
var order = new Order(data);
await order.save();
}
order-route.js:
'use strict';
const express = require('express');
const router = express.Router();
const controller = require('../controllers/order-controller');
const authService = require('../services/auth-service');
router.get('/', authService.authorize, controller.get);
router.post('/', authService.authorize, controller.post);
module.exports = router;
This can happen if you are debugging your nodejs server and it's caught on a breakpoint. If so, the response will hang. To fix it, just disable that breakpoint, restart your nodejs server, and issue the request again with Postman.
Maybe you are using a GET request in the postman instead of POST request.
Make sure that they comply with the type.
Related
I've got a react project setup along with a server using the MERN stack.
I'm trying to implement longpolling into my project and its working all fine and dandy, but in my browser whenever i refresh the page without first updating the database to let the server answer the "get request", i get an error saying
Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
Says it can be found in PollingTest.js:9
//Client
//PollingTest.js
import React, { useEffect } from 'react'
export default function PollingTest() {
async function LongPolling(){
const res = await fetch("http://localhost:3001/poll")
const data = await res.json()
console.log(data)
LongPolling();
}
useEffect(()=>{
LongPolling();
},[])
return (
<div>PollingTest</div>
)
}
//Server
//server.js
const express = require('express');
const app = express();
const path = require("path");
const mongoose = require('mongoose');
const db = {};
const Schema = mongoose.Schema;
const errandSchema = new Schema({
roomNr: {type: Number, required: true, min: 0},
category: {type: String, required: true},
roles: [String],
title: {type: String, required: true},
text: {type: String, required: false},
status: {type: Number, required: true, min: 0, max: 2},
highPriority: {type: Boolean, required: true},
opened: {type: Date, required: true},
closed: {type: Date, required: false}
});
db.errand = mongoose.model('Errand', errandSchema);
const cors = require('cors');
app.use(cors({ origin: "http://localhost:3000" }));
app.use(express.json());
const mongoURI = "mongodb://DESKTOP-LHCS5UA:27017/database";
const port = process.env.PORT || 3001;
mongoose.connect(mongoURI)
.then(() => {
console.log('Connected to mongo!');
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
});
})
.catch((err) => {
console.log(err);
process.exit();
});
app.get('/poll', async (req, res, next) => {
senseChange()
.then(data =>{
res.send(data);
console.log(data);
})
})
function senseChange() {
return new Promise((resolve) => {
changeStream = db.errand.watch();
changeStream.on('change', data => {
console.log("Update done!");
resolve(data)
})
});
}
I keep getting a 404 when I am posting to a route. I am using MongoDB, express and React Native. I have created the Schema, actions and router.
The Schema is below:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create Edible Schema
const EdiblesSchema = new Schema({
name: {
type: String,
required: true
},
price: {
type: String,
required: true
},
strength: {
type: String,
required: true
},
purchasedLocation: {
type: String,
required: true
},
effects: {
type: String,
required: true
},
strain: {
type: String,
required: true
},
});
module.exports = Edibles = mongoose.model("edibles", EdiblesSchema);
Then the post router is below:
const express = require("express");
const router = express.Router();
const keys = require("../../config/keys");
// Load edibles model
const Edibles = require("../../models/edibles");
// #route POST api/users/edibles
// #desc Add an edible to the users collection
// #access Public
router.post ('/edibles', (req, res) => {
if (res.status === 200) {
const newEdible = new Edibles({
name: req.body.name,
price: req.body.price,
strength: req.body.strength,
strain: req.body.strain,
purchasedLocation: req.body.purchasedLocation,
effects: req.body.effects,
})
} else {
return res.status(400).json({ email: "Thats not going to get you high" });
} newEdible
.save()
.then( edibles => res.json(edibles))
.catch(err => console.log(err))
});
module.exports = router;
Then the finale we have the handleSubmit to send the users info to the api endpoint.
const handleSubmit = (response) => {
console.log("EDIBLES", name, strength, price, effects, strain)
dispatch(setEdible(payload))
if (response === 200) {
axios
.post(edibleApi, payload)
console.log("PAYLOAD", edibleApi, payload, setEdible)
// navigation.navigate("Dashboard")
} else {
console.log("WRONG", edibleApi, payload, setEdible);
console.log("userEdibles", userEdibles)
}
}
I am really lost with this... Please help!
The issue was that I was using the wrong endpoint. I worked this out by using the express-list-routes by adding it to my server.js file.
const expressListRoutes = require('express-list-routes');
const router = express.Router();
console.log("Now we cooking with gas", expressListRoutes(app, { prefix: '/api/v1' })))
That console.log must be added to the console.log that indicates if your server is running or not....
// Creating one
router.post('/', async (req, res) => {
const post = new Post({
title: req.body.title,
category: req.body.category,
content: req.body.content,
author: req.body.author,
postDate: req.body.postdate,
postTags: req.body.posttags
})
try {
const newPost = await post.save()
res.status(201).json(newPost)
} catch (err) {
res.status(400).json({ message: err.message })
}
})
I am working with API server in node but after asking for the POS call from client end the response is
post validation failed: title: Path title is required.
the model for mondoDB is
const mongoose = require('mongoose')
const postSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
category:{
type: String,
required : true
},
content: {
type: String,
required: true
},
author :{
type : String,
required : true
},
postDate: {
type: Date,
required: true,
default: Date.now
},
postTags : {
type : Array,
default : ["Coding"]
}
})
module.exports = mongoose.model('post', postSchema)
Given you are using express. This goes in the main file after app initialization. So that your application is able to parse data from the json it is receiving from front end.
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
In case you don't use body parser you won't be able to access those data. So please check that out.
For those who not installed body parser follow this steps.
Run this common on terminal/cmd on project root path (installing body parser)
npm i body-parser
Import bodyParser on main file
var bodyParser = require('body-parser');
Use middle wire ( Choose only one that's correct for you based on the type of data you pass to POST request)
a. router.use(bodyParser.json({ type: 'application/*+json' })); // parse various different custom JSON types as JSON
b. router.use(bodyParser.raw({ type: 'application/vnd.custom-type' })); // parse some custom thing into a Buffer
c. router.use(bodyParser.text({ type: 'text/html' })); // parse an HTML body into a string
Also do your imports above
// Creating one
router.post('/', async (req, res) => {
const post = new Post({
title: req.body.title,
category: req.body.category,
content: req.body.content,
author: req.body.author,
postDate: req.body.postdate,
postTags: req.body.posttags
})
try {
const newPost = await post.save()
res.status(201).json(newPost)
} catch (err) {
res.status(400).json({ message: err.message })
}
})
More on body parser : https://www.npmjs.com/package/body-parser
for exemple I have a user model like this
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
username: {
type: String,
required: true,
},
Points: {
type: Number,
default: 0,
},
module.exports = User = mongoose.model("users", UserSchema);
then I want to execute a function automatically when user.points is equal to 10 with express js, is there any solution ?
#Yessine, may you should try something like this. You can add checkForPoints wherever you are updating the Points and proceed with your things,
const { Users } = require('/schema.js');
const checkForPoints = async (username) => {
await Users.findOne({ username }, function (err, data) {
if (err) {
console.log("enter error ------", err)
}
if (data && data.Points === 10) {
// Execute your code
}
});
};
// Users schema(schema.js)
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('your db', { useNewUrlParser: true });
const requestSchema = mongoose.Schema({
_id: mongoose.Types.ObjectId,
username: String,
Points: Number
});
module.exports = mongoose.model('users', requestSchema);
Polling is a technique where we check for fresh data over a given interval by periodically making API requests to a server.enables you to periodically check for the newest values of data and do further requests once it enters the desired state.
What I'm trying to do:
I have a small Node app makes a request to an API to get data about the stock market and then saves the data to a Mongo DB (already made and working), which I would like to run constantly. Next I need to build an API which allows my other servers/apps to get that data being (not made yet).
I think Express is a good choice although I know there are other options. I am getting this code from another API that I built for a MEAN stack app and have been looking around to troubleshoot.
My main issue is that most tutorials show how to just build a CRUD API for the MEAN, MERN, and other stacks. I'm not really sure how to structure this system or Node apps can run independently of one another in the way that I am describing.
Currently I am not getting any errors when I run the app but I am not able to get anything when I go to my endpoints.
When I first started I thought that the standalone Node app (request and writing data part of this) could live within the same file as the Express part, but now I don't think that would work and have split those into separate files. I have seen PM2 and other ways of making the node app into a background service?
Not totally sure, some clarification on that, as well as some help with why my express API endpoints won't respond with data from the database. Here is my code.
Standalone app:
const request = require('request');
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const d = new Date();
let day = d.getDay()
let hour = d.getHours();
const stockMomentSchema = new Schema({
symbol: String,
price: Number,
size: Number,
time: {type: Date, default: Date.now}
});
const StockMoment = mongoose.model('stockMoment', stockMomentSchema, 'stockPriceData');
mongoose.connect('mongodb://localhost:27017/stock-test')
.then(() => {
console.log('connected');
})
.catch(err => {
console.error(err);
});
function makeRequest() {
if(day <= 1 || day >= 5) {
if(hour >= 10 || hour <= 15) {
getMarketData();
}
}
}
function getMarketData() {
request({
url: 'https://api.iextrading.com/1.0/tops/last',
json: true
}, (err, res, body) => {
if(err) {
return console.error(err);
}
for(let i = 0; i < body.length; i++) {
const stockMoment = new StockMoment({
symbol: body[i].symbol,
price: body[i].price,
size: body[i].size,
time: body[i].time,
});
stockMoment.save((err) => {
if(err) return handleError(err);
console.log('Saved!', i);
});
console.log(body[i]);
}
});
}
makeRequest();
//setInterval(makeRequest, 5000);
server.js:
const express = require('express');
const path = require('path'); // Not sure if this is needed
const http = require('http');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();
const api = require('./api');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cors());
//app.use(express.static(path.join(__dirname, 'dist'))); // Not sure if this is needed
app.use('/api', api);
app.get('*', function(req, res) {
res.status(404);
});
const port = process.env.PORT || '3000';
app.set('port', port);
const server = http.createServer(app);
server.listen('3000', function() {
console.log('--------------------');
console.log('Server running');
console.log('You can view the server at http://localhost:3000');
console.log('If you are running an Angular app on while using this server please use http://localhost:4200');
console.log('--------------------');
});
stock model:
const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const StockSchema = mongoose.Schema({
username: { type: String, unique: true, required: true },
password: { type: String, required: true },
email: {type: String, required: true},
phoneNumber: {type: String, required: true},
company: {type: String, required: true},
about: {type: String, required: true},
userType: {type: String, required: true}
});
StockSchema.plugin(uniqueValidator);
module.exports = mongoose.model('Stock', StockSchema);
api.js:
const express = require('express');
const router = express.Router();
const Stock = require('./stock.js');
router.get('/', function(req, res, err) {
console.log('Hello world');
});
router.get('/stocks/:id', function(req, res, err) {
console.log('Hello world');
const stockData = {
_id: false,
symbol: true,
price: true,
size: true,
time: true
}
Stock.findById(req.params.id, stockData, function(err, stock) {
if(err) {
res.send('No stocks found');
console.log(err);
} else {
res.json(stock);
}
});
});
module.exports = router;
Edit:
Added mongoose.connect to server.js but it still doesn't work
mongoose.connect('mongodb://localhost:27017/stock-test')
.then((res) => {
console.log('connected');
})
.catch(err => {
console.error(err);
});
Edit: Here's a gist with the working changes https://gist.github.com/drGrove/3e6699ded09f282e528a661fb41439e1
Your api is pulling in a schema that has no information associated with it.
You should break out the StockMomentData, require it from you api.js and use that in your get request by id instead of your current stock model.
Since your mongoose connection is shared between the two "applications" you can pull that out into a db.js and just require that file on load for each project (But that can always be done at a later time).
Just note that you do need a connection in either your Model file or your api.js file so that mongoose actually connects to the mongo database
Initial Answer:
Your API server is missing a connection to Mongo via mongoose. You'll have to have a connection call just like what you have in your "standalone app".