mongodb is creating a test db automatically - mongodb

I have created a MongoDB database named: "helsinki_city_bike" and I uploaded CSV data using MongoDB compass in the collection name: "journey_detail". I also connected the database to atlas using a connection string. Now that I want to fetch the data from the database it's creating another test db and collection name "journey_detail" inside "helsinki_city_bike".
how can I fetch data from my collection without creating an empty collection?
the function is working well as I am getting an empty array. what I am doing wrong with the model?
This is my schema:
import mongoose from "mongoose";
export const journeySchema = mongoose.Schema({
Departure_time: String,
Return_time: String,
Departure_Station_Id: Number,
Departure_Station_Name: String,
Return_Station_Id: Number,
Return_Station_Name: String,
Covered_Distance: Number,
Duration: Number,
});
export const journey_detail = mongoose.model("journey_detail", journeySchema);
req function:
import { journey_detail } from "../models/Schema.js";
export const getJourneyDetails = async (req, res) => {
try {
const JourneyDetails = await journey_detail.find().limit(10);
if (!JourneyDetails) {
return res.status(404).json({ message: "Journey Details not found" });
}
res.status(200).json(JourneyDetails);
} catch (error) {
console.error(error);
res.status(500).json({ message: "Error retrieving Journey Details" });
}
};
connection:
const app = express();
dotenv.config();
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
app.use("/", router);
mongoose
.connect(process.env.CONNECTION_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() =>
app.listen(3001, () => console.log(`server running on the port ${3001}`))
)
.catch((error) => console.log(error));
mongoose.set();
mongoose.connection.on("open", () => {
console.log("Mongoose connected.");
});

Related

fetch data's from existing collection

I have created a MongoDB database named: "helsinki_city_bike" and I uploaded CSV data using MongoDB compass in the collection name: "journey_detail". I also connected the database to atlas using a connection string. Now that I want to fetch the data from the database it's creating another test db and collection name "journey_detail" inside "helsinki_city_bike".
how can I fetch data from my collection without creating an empty collection?
the function is working well as I am getting an empty array. what I am doing wrong with the model?
This is my schema:
import mongoose from "mongoose";
export const journeySchema = mongoose.Schema({
Departure_time: String,
Return_time: String,
Departure_Station_Id: Number,
Departure_Station_Name: String,
Return_Station_Id: Number,
Return_Station_Name: String,
Covered_Distance: Number,
Duration: Number,
});
export const journey_detail = mongoose.model("journey_detail", journeySchema);
req function:
import { journey_detail } from "../models/Schema.js";
export const getJourneyDetails = async (req, res) => {
try {
const JourneyDetails = await journey_detail.find().limit(10);
if (!JourneyDetails) {
return res.status(404).json({ message: "Journey Details not found" });
}
res.status(200).json(JourneyDetails);
} catch (error) {
console.error(error);
res.status(500).json({ message: "Error retrieving Journey Details" });
}
};
connection:
const app = express();
dotenv.config();
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
app.use("/", router);
mongoose
.connect(process.env.CONNECTION_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() =>
app.listen(3001, () => console.log(`server running on the port ${3001}`))
)
.catch((error) => console.log(error));
mongoose.set();
mongoose.connection.on("open", () => {
console.log("Mongoose connected.");
});

Mongoose const castError = new CastError();

I seem to be getting this error:
C:\...\node_modules\mongoose\lib\query.js:4638
const castError = new CastError();
^
CastError: Cast to ObjectId failed for value "undefined" (type string) at path "_id" for model "cProd"
at model.Query.exec (C:\...\node_modules\mongoose\lib\query.js:4638:21)
at model.Query.Query.then (C:\...\node_modules\mongoose\lib\query.js:4737:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
messageFormat: undefined,
stringValue: '"undefined"',
kind: 'ObjectId',
value: 'undefined',
path: '_id',
reason: BSONTypeError: Argument passed in must be a string of 12 bytes or a string of 24 hex characters
at new BSONTypeError (C:\...\node_modules\bson\lib\error.js:41:28)
at new ObjectId (C:\...\node_modules\bson\lib\objectid.js:65:23)
at castObjectId (C:\...\node_modules\mongoose\lib\cast\objectid.js:24:12)
at ObjectId.cast (C:\...\node_modules\mongoose\lib\schema\objectid.js:247:12)
at ObjectId.SchemaType.applySetters (C:\...\node_modules\mongoose\lib\schematype.js:1180:12)
at ObjectId.SchemaType._castForQuery (C:\...\node_modules\mongoose\lib\schematype.js:1615:15)
at ObjectId.SchemaType.castForQuery (C:\...\node_modules\mongoose\lib\schematype.js:1605:15)
at ObjectId.SchemaType.castForQueryWrapper (C:\...\node_modules\mongoose\lib\schematype.js:1582:20)
at cast (C:\...\node_modules\mongoose\lib\cast.js:341:32)
at model.Query.Query.cast (C:\...\node_modules\mongoose\lib\query.js:5073:12),
valueType: 'string'
}
for this code:
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const cProd = require('./models/cProd');
mongoose.connect('mongodb://localhost:#/database', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('Database connected');
});
const app = express();
// app.engine('ejs', ejsMate)
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'))
// Parsing request.body
app.use(express.urlencoded({extended: true}))
app.get('/', (req, res) => {
res.render('main')
});
app.get('/cProds', async (req, res) => {
const cProds = await cProd.find({});
res.render('cProds/index', {cProds})
});
app.get('/cProds/create', (req, res) => {
res.render('cProds/create');
})
app.post('/cProds', async (req, res) => {
const conProd = new cProd(req.body.cProd);
await conProd.save();
res.redirect(`/cProds/${cProd._id}`)
});
app.get('/cProds/:id', async (req, res) => {
const conProd = await cProd.findById(req.params.id)
res.render('cProds/show', {conProd})
});
app.listen(3000, () => {
console.log('Serving on port #')
})
The app.post above seems to work when I do a simple res.send(req.body), but I get this error if I finish the code.
Dumb question, is it possibly due to not installing UUID? I don't believe I have yet.
Please help - complete beginner here who has exhausted research and figuring this out.
UPDATE: Schema and Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const opts = {toJSON:{virtuals:true}};
const CProdSchema = new Schema({
product_name: String,
type: String,
description: String
}, opts);
CProdSchema.virtual('properties.popUpMarkup').get(function() {
return `
<strong>${this.product_name}</strong>
<p>${this.description.substring(0,20)}...</p>`
});
module.exports = mongoose.model('cProd', CProdSchema)
Ah, I think I was blind.
Your problem method:
app.post('/cProds', async (req, res) => {
const conProd = new cProd(req.body.cProd);
await conProd.save();
res.redirect(`/cProds/${cProd._id}`)
});
You want to send the user to the url for the newly created cProd. But cProd is the model name, while conProd is the new document created.
Simply change the last line:
res.redirect(`/cProds/${conProd._id}`)
To avoid the confusion in future, I recommend sticking to capitalized first letter of models. I'm making a guess at the name, so for example:
const CampgroundProduct = require('./models/cProd');
And any instances (documents) of this model can be called campgroundProduct or simply product.
As to how that specific error code happened, I'm guessing that model._id references the creator for that type of field, which would be mongoose.Types.ObjectId()

How to get all the collections of MongoDB?

I want to get access to all the collections of my MongoDB database.
But I am unable to do so.
I am using mongoose.connection.db.getCollection(collection_name) just above the listen part of code but console is saying
mongoose.connection.db.getCollection is not a function.
Here is my code
import express from "express";
import mongoose from "mongoose";
import Messages from "./messages.js";
import dynamicModel from "./messagesRoom.js";
import cors from "cors";
// app configuration
const app = express();
const port = process.env.PORT || 9000;
//middleware
app.use(express.json());
app.use(cors());
// DB Configuration
const url = "mongodb+srv://username:password#cluster0.zp9dc.mongodb.net/Whatsapp_MERN";
mongoose.connect(url, {useCreateIndex: true, useNewUrlParser: true, useUnifiedTopology: true})
.then(()=> console.log('mongoDB is connected'))
.then(err => console.log(err));
const db = mongoose.connection;
db.once('open', () => {
console.log("DB is connected");
const msgCollection = db.collection('messagecontents');
const changeStream = msgCollection.watch();
changeStream.on('change', (change) => {
console.log(change);
if(change.operationType === 'insert'){
const msgDetails = change.fullDocument;
pusher.trigger('messages', 'inserted',
{
name: msgDetails.name,
message: msgDetails.message,
timestamp: msgDetails.timestamp,
received: msgDetails.received,
})
}
else{
console.log('Error triggering pusher');
}
})
})
// API routes
app.get("/", (req, res) => {
res.status(200).send("Hello World");
})
app.get("/messages/sync", async (req, res) => {
await Messages.find( (err, data) => {
if(err){
console.log(err);
res.status(500).send(err);
}else{
res.status(200).send(data);
}
})
})
app.post("/changeChat", (req, res) => {
const collection_name = req.body.chatName;
let collection = mongoose.connection.db.getCollection("collection_name");
console.log(collection);
})
// listening part
app.listen(port, () => console.log(`listening on port number ${port}`));
please suggest me a way using which I can get access to collections of database according to the name I am using.
mongoose.connection.on('open', function (ref) {
mongoose.connection.db.listCollections().toArray(function(err, names){
console.log(names)
})
})
Try this code block below "mongoose.connect()", the 'listCollections()' function will return the list of all the collection in the respective database and 'toArray()' function will convert that list into array, then we simply log the array.

I am trying to store my node rest api data to mongodb atlas. But getting insertion errors

I am trying to register the user to mongodb atlas for registration and login but i am geting an error 404.
here is full link to mycode
https://github.com/badrinathareddyr/falcon.git
server.js file
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const authRoute = require('../backend/routes/auth')
//connect to database
dotenv.config({ path: __dirname + '/.env' });
mongoose.connect(
process.env[DB_CONNECT], { useNewUrlParser: true }, () =>
console.log('connected to db!')
);
//Middleware
app.use(express.json());
//middlewareroutes
app.use('/register', authRoute);
app.listen(3000, () => console.log('server up and running'));
auth.js file
var express = require('express');
const router = express.Router();
const User = require('../models/User');
const bcrypt = require('bcryptjs');
router.post('/register', function (req, res) {
if (!req.body.email || !req.body.password) {
res.json({ success: false, msg: 'Please pass email and password.' });
} else {
var newUser = new User({
email: req.body.email,
password: req.body.password
});
// save the user
newUser.save(function (err) {
if (err) {
return res.json({ success: false, msg: 'Email already exists.' });
}
res.json({ success: true, msg: 'Successful created new user.' });
});
}
});
module.exports = router;
It's because of process.env.DB_CONNECT in your code is undefined. Change line 5 of your src/backend/server.js file like below:
const dotenv = require('dotenv').config({ path: __dirname + '/.env' });
then comment dotenv.config()
and copy .env to src/backend/.
Or change line 10 or the file like this:
dotenv.config({ path: __dirname + '/.env' });
You have const User = require('../models/User'); two time in backend/routes/auth.js. Comment line 9. It will give you error.
I fixed it and created pull request in github. Merge it.

How to Use Rest api with React Native; Network Call Issues

I am newbie in React Native,
I made a simple back-end using Mongodb and express routes etc in MongoDb atlas. I am successfully able to post/get/patch/Delete operation on mongodb atlas that store Title and Description using Postman. Everything is working fine.
Here comes the problem First when i make a simple frontend in ReactNative that take inputs Title and Description. I want application that take simple input of Title and Description and on Submit Button it store into the the mongodb Atlas just like postman is doing. I tried but its not working code is below. I dont know how to communicate the front end into backend. I watch alot of tutorials but unable to get the point.
Secondly, when i make a server i wrote in pakage.json > "start": "nodemone server.js" and i need to run ReactNative app i update the pakage.json > "start": "expo start" to run app. How can i run server and expo app same time? if i seprate the app folder then how can i connect both of them.
below is my Code.
Routes folder post.js
const express = require( 'express' );
const router = express.Router();
const Post = require ('../models/Post')
//Gets back all the posts
router.get ( '/', async (req, res) =>{
try{
const post = await Post.find();
res.json(post);
}catch (err) {
res.json({message: err })
}
});
//To Submit the Post
router.post('/', async (req, res) =>{
//console.log(req.body);
const post = new Post({
title: req.body.title,
description: req.body.description
});
try{
const savedPost = await post.save();
res.json(savedPost);
}catch (err) {
res.json ({ message: err })
}
});
//Get back specific Post
router.get('/:postId', async (req, res) =>{
try{
const post= await Post.findById(req.params.postId);
res.json(post);
}catch(err) {
res.json({message: err });
}
})
// to delete specific post
router.delete('/:postId', async (req, res) =>{
try{
const removePost= await Post.remove({_id: req.params.postId});
res.json(removePost);
}catch(err) {
res.json({message: err });
}
})
//update Post
router.patch('/:postId', async (req, res) =>{
try{
const updatePost = await Post.updateOne(
{_id: req.params.postId},
{ $set:
{title: req.body.title}
});
res.json(updatePost);
}catch(err) {
res.json({message: err });
}
})
module.exports = router;
Defined Schema Post.js
const mongoos = require( 'mongoose' );
const PostSchema = mongoos.Schema ({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
})
module.exports = mongoos.model ('Post', PostSchema); // giving this schma name Post
server.js
const express = require( 'express' );
const app = express();
var mongo = require('mongodb');
const mongoos = require( 'mongoose' );
const bodyParser = require('body-parser');
require('dotenv/config');
const postRoute = require('./Routes/post');
app.use(bodyParser.json());
app.use ('/post', postRoute);
app.get ( '/', (req, res) =>{
res.send('We are on Home ')
});
// connecting to database
mongoos.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true },
() => console.log('Connected to db')
);
app.listen(3000);
Frontend Form.js
import React from 'react';
import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native';
class Form extends React.Component{
constructor(){
super();
this.State = {
title: '',
description: ''
}
}
getInput(text, field){
if(field == 'title')
{
this.setState({ title: text, })
}
else if(field == 'description')
{
this.setState({ description: text, })
}
//console.warn(text)
}
submit(){
let collection={}
collection.title = this.state.title,
collection.description = this.state.description;
console.warn(collection);
var url = process.env.DB_CONNECTION ;
fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
collection
}),
});
}
render() {
return (
<View style={styles.container}>
<TextInput style={styles.inputBox}
underlineColorAndroid= 'rgba(0,0,0,0)'
placeholder='Title'
selectionColor="#fff"
keyboardType="default"
onChangeText = {(text) => this.getInput(text, 'title')}
/>
<TextInput style={styles.inputBox}
multiline = {true}
numberOfLines = {4}
underlineColorAndroid= 'rgba(0,0,0,0)'
placeholder='Description'
selectionColor="#fff"
keyboardType="default"
onChangeText= {(text) => this.getInput(text, 'description')}
/>
<TouchableOpacity onPress={()=>this.submit()} style={styles.btn} >
<Text style={{textAlign: 'center'}}>Submit</Text>
</TouchableOpacity>
</View>
);
}
}
export default Form;
Here comes a very basic solution to your problem:
1: if you are using Rest API based model of communication go for Two separate repos on GITHUB. One for React native app of yours and one for server-side of yours.
2: now to go to Heroku.com and make an app there and attach your card there in order to use the full Free Sandbox functionality
3: create a project there and find an option to deploy from Github.
4: for data communication aka network requests its easy to use axios rather than Fetch
for best practices use :
https://riptutorial.com/react-native/topic/857/getting-started-with-react-native
5: in order to run more than one command in package json able to run multiple scripts in package.json you can either do it like
scripts:{"run": "yarn start" && "react-native-expo"}
6: or if your scripts are like they gonna need to run constantly in the background it's better that you create two separate scripts
scripts:{"run1": "yarn start", "run2":"yarn start2"}
7: I see you are not handling the AsyncAwait Try catch or Promise after the fetch
8: you are also not hitting the server-side URL seemingly you are hitting DB connection url. what you should be doing is that you hit the POST/GET/UPDATE routing endpoint of yours