I recently developed a react app with nodejs which depends on mongodb for its data. I have also just installed mongodb on Google Compute Engine and opened port 27017. However, my question is, how can i connect my application (I am using Mongoose) to the VM Instance.
Here is the connection string on localhost (my local machine), what should I change it to:
module.exports = {
url: 'mongodb://localhost:27017/dapashirts'
}
Here is my server.js file:
const express = require('express');
const bodyParser = require('body-parser');
const cors = require("cors");
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
// Configuring the database
const dbConfig = require('./config/database.config.js');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
// Connecting to the database
mongoose.connect(dbConfig.url, {
useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true
}).then(() => {
console.log("Successfully connected to the database");
}).catch(err => {
console.log('Could not connect to the database. Exiting now...', err);
process.exit();
});
// Require routes
require('./routes/department.routes.js')(app);
require('./routes/category.routes.js')(app);
require('./routes/product.routes.js')(app);
require('./routes/order.routes.js')(app);
app.listen(3500, () => {
console.log("Server is listening on port 3500");
});
Here is a sample model:
const mongoose = require('mongoose');
const ProductSchema = mongoose.Schema({
category_id: {
type: [mongoose.Schema.Types.ObjectId],
required: true
},
name: {
type: String,
required: true,
unique: true
},
description: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
discounted_price: {type: Number, default: 0.00},
image: String,
image_2: String,
thumbnail: String,
display: { type: Number, min: 0, max: 3, default: 0 }
});
module.exports = mongoose.model('Product', ProductSchema);
Here is a sample route:
module.exports = (app) => {
const products = require('../controllers/product.controllers.js');
// Create a new product
app.post('/products', products.create);
// Retrieve all products
app.get('/products', products.findAll);
// Retrieve a single product with productId
app.get('/products/:productId', products.findOne);
// Retrieve a products with categoryId
app.get('/products/:categoryId', products.findWithCategoryId);
// Update a product with productId
app.put('/products/:productId', products.update);
// Delete a produt with productId
app.delete('/products/:productId', products.delete);
}
How do i also transfer my localhost database to Google Compute Engine
The easiest way is to use a database as a service (daas) from Mongo DB:
https://www.mongodb.com/cloud/atlas
Related
I am trying to create a sample API of restaurants using POST but after starting API and loading it into Postman it does not show results.
router.js
const express = require('express');
const restaurantController = require('../Controllers/restaurantData');
const router = express.Router();
router.post('/restaurantFilter',(req, res) => {
restaurantController.getfilter
});
module.exports = router;
app.js
const express = require('express');
const bodyparser = require('body-parser');
const mongoose = require('mongoose');
const apiRouter = require('./Routes/router');
const port = 4005;
const app = express();
app.use(bodyparser.json());
app.use('/api', apiRouter);
mongoose.connect(
'mongodb://127.0.0.1:27017/sample',
{ useNewUrlParser: true, useUnifiedTopology: true }
).then(success => {
console.log('Connected to MongoDB');
app.listen(port, () => {
console.log(`Server started at port ${port}`);
});
}).catch(error => {
console.log(error);
});
restaurant.js (Controller)
const restaurants = require('../Models/restaurantData');
exports.getfilter = (req, res) => {
const city_name = req.body.city_name;
const cost = req.body.cost;
restaurants.find({
city_name: city_name,
cost: cost
}).then(result => {
res.status(200).json({
message: "Filtered Data",
result
})
}).catch(error => {
res.status(500).json({
message: error
})
})
}
restaurantData.js (Model)
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const restaurantSchema = new Schema({
name: {
type: String,
required: true
},
city_name:{
type: String,
required: true
},
city: {
type: Number,
required: true
},
area: {
type: Number,
required: true
},
locality:{
type: String,
required: true
},
thumb: {
type: String,
required: true
},
cost:{
type: Number,
required: true
},
address:{
type: String,
required: true
},
mealtype:{
type: Number,
required: true
},
name:{
type: String,
required: true
},
cuisine:{
type: Number,
required: true
},
type:{
type: Array,
required: true
},
Cuisine:{
type: Array,
required: true
}
});
module.exports = mongoose.model('restaurantData', restaurantSchema, 'restaurantData');
I think mostly it is the router problem but trying to know where? So, share any ideas. Thank You.
This request handler:
router.post('/restaurantFilter',(req, res) => {
restaurantController.getfilter
});
Does not actually call the getfilter function so nothing is ever sent from the POST request. You can fix that by either doing this:
router.post('/restaurantFilter', restaurantController.getfilter);
or this:
router.post('/restaurantFilter',(req, res) => {
restaurantController.getfilter(req, res);
});
Then, it looks like you also have to property export and import that getfilter() function. You appear to export it just fine in restaurant.js:
exports.getfilter = (req, res) => { ... });
But, you don't seem to be importing the controller properly as you're doing this:
const restaurantController = require('../Controllers/restaurantData');
When it looks like you should be doing this:
const restaurantController = require('../Controllers/restaurant.js');
so that you're assigning the controller the object that actually has the getfilter method on it.
I am beginner studying node.js, REST API and MongoDB by following some online resources. I tried to use the keyword "require" in my following code so that the users are not allowed to input blank value:
ninjas.js (create schema and models)
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
//create Schema and model
const NinjaSchema = new Schema({
name:{
type: String,
require: [true,'Name field is required']
},
rank:{
type: String,
require: [true,'This field is required']
},
available:{
type: Boolean,
default: false,
require: [true,'This field is required']
}
//add in geo loction
});
const Ninja = mongoose.model('hi ninja',NinjaSchema);
module.exports = Ninja;
Below is the code handling the API:
api.js
const express = require('express');
const Ninja = require('../models/ninjas');
const router = express.Router();
//get a list of ninjas from the database
router.get('/ninjas',(req,res,next)=>{
res.send({type: 'GET'});
})
//add a new ninjas to the database
router.post('/ninjas',(req,res,next)=>{
//create a Ninja object and save it to DB
Ninja.create(req.body).then((ninja) => {
res.send(ninja)
}).catch(next);
})
//update a ninjas in the database
router.put('/ninjas/:id',(req,res,next)=>{
res.send({type: 'PUT'});
})
//delete a ninjas from the database
router.delete('/ninjas/:id',(req,res,next)=>{
res.send({type: 'DELETE'});
})
module.exports = router;
Below is the main program:
index.js
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
//set up express app
const app = express();
//connect to mondodb
mongoose.connect("mongodb://localhost/ninjago",{
useNewUrlParser: true,
useUnifiedTopology: true,
});
mongoose.Promise = global.Promise;
//body parser middleware
app.use(bodyParser.json());
//initialize routes
app.use('/api',require('./routes/api'));
//error handling middleware
app.use((err,req,res,next) => {
//console.log(err);
res.status(422).send({error: err.message});
});
//listen for requests
app.listen(process.env.port || 4000,() => {
console.log('now listening for requests');
});
However, when I tried to use POSTMAN to test the API, I found that even I did not some parameter, the system would still return a successful message.
May I know if there is something wrong or missing in my code causing the "require" keyword not working? Thank you so much!
Hon
Replace require with the keyword required in your schema
const NinjaSchema = new Schema({
name:{
type: String,
required: [true,'Name field is required']
},
rank:{
type: String,
required: [true,'This field is required']
},
available:{
type: Boolean,
default: false,
required: [true,'This field is required']
}
//add in geo loction
});
See this for reference.
I am new to sequelize and I created a middleware called "db.js" with a connection to a mysql table called "users". Everytime, I attempt to run the app.js, I am getting this error: "TypeError: app.use() requires a middleware function".
However, I have a middleware function. See the code below: Am I missing something? I have the module.exports object at the end.
Should I have initialize sequelize?
db.js file
const Sequelize = require("sequelize");
const mysql = require("mysql");
const mysql2 = require("mysql2");
const db = {}
const sequelize = new Sequelize("smalldata", "root", "xxxx", {
host: "localhost",
dialect: "mysql",
operatorsAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 90000
}
})
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
db.sequelize = sequelize
db.Sequelize = Sequelize
module.exports = db;
app.js file
const sequelize = require("sequelize");
const db = require("./middleware/db");
const express = require("express");
//Initialize Middleware
app.use(cors());
app.use(expressLayouts);
app.use(logger);
app.use(db);
user.js file
const Sequelize = require("sequelize");
const db = require("./db");
const User = db.sequelize.define(
'users',
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
first_name: {
type: Sequelize.STRING
},
last_name: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
}
},
{
timestamps: true
},
)
// Note: using `force: true` will drop the table if it already exists
User.sync({ force: true }).then(() => {
// Now the `users` table in the database corresponds to the model
definition
return User.create({
first_name: 'John',
last_name: 'Hancock',
email:'johnhancock#gmail.com',
password:'johnny'
});
});
module.exports = User
I found the error:
Capitalize error in app.js file:
const Sequelize = require("sequelize");
instead of:
const sequelize = require("sequelize");
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".
Here is my code
file name student.js
var mongoose = require('mongoose');
var studentSchema = new mongoose.Schema({
name:{
type: String,
required: true
},
rollno:{
type: Number,
required: true
},
grade:{
type: String,
required: true
},
result:{
type: String,
required: true
}
});
var Student = module.exports = mongoose.model('Student',studentSchema);
module.exports.getStudents = function (callback){
Student.find(callback);
}
**filename app.js**
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var PORT= process.env.PORT || 3000;
Student = require('./models/student');
mongoose.connect('mongodb://localhost/register');
var db= mongoose.connection;
app.get('/api/student', function (req,res){
Student.getStudents(function (err, student){
if(err){
throw err;
}
res.json(student);
});
});
app.listen(PORT);
console.log('Running app on port:' + PORT);
If you have an existing collection that you want to query using Mongoose, you should pass the name of that collection to the schema explicitly:
var studentSchema = new mongoose.Schema({ ... }, { collection : 'student' });
If you don't, Mongoose will generate a collection name for you, by lowercasing and pluralizing the model name (so documents for the model Student will be stored in the collection called students; notice the trailing -s).
More documentation here.