How to filter Data using email in MongoDB? - mongodb

How can I get data by email from MongoDB? Here is an example:
_id: Objectid('6274e58826914a298567e5f8'),
"name": "Vauxhall Mokka",
"supplier": "Vauxhall",
"email": "abc#def.com",
"price": 30000,
"quantity": 30,
"img": "https://i.ibb.co/SQqBNXy/getImage.png",
"sold": 0
I can easily get the item by _id with this code:
app.get('/cars/:id', async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await serviceCollection.findOne(query);
res.send(result);
});
But why I couldn't do the same with email? when I apply '/cars/:email', the server goes down. If I get the item with id, then why cannot get it with the email?

No reason why this shouldn't work
app.get('/cars/:email', async (req, res) => {
const query = { email: req.params.email };
const result = await serviceCollection.findOne(query);
res.send(result);
});
When the "server goes down", is it giving you an error message?

Your email is missing in node js code you have to grave email from req as like this
const email = req.query.email

the problem is you already have another endpoint with "/cars/" you need to change "/(here)/" ... like "/carsByEmail/:email". This happens when you declare another same endpoint with app.get method. You should try this enter code here
app.get('/carsByEmail/:email', async (req, res) => {
const query = { email: req.params.email };
const result = await serviceCollection.findOne(query);
res.send(result);
});
you already have this endpoint, this two are (1)=> "/cars/:id" and (2)=> "/cars/:email" the same get method. so that's why it's giving you BSONType error. and it also collaborates with the other same endpoint. So you should change the main endpoint name.. Like (1)=> "/carsById/:id" and (2)=> "/carsByEmail/:email" now everything is perfect withe the same get/put/patch method. just change the main part of the API endpoint. Thank you
app.get('/cars/:id', async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await serviceCollection.findOne(query);
res.send(result);
});

Related

Submit Data in mongoDB

I am trying to submit my data using mongoose in my NEXT app, I am able to fetch data using getServerSideProps like
export async function getServerSideProps(context) {
const data = await shop.findOne({ shopName: "testing" });
return {
props: {
dbData: JSON.stringify(data),
}, // will be passed to the page component as props
};
}
Now I want to put some data in my mongoDb is there any method that will run after my button click and renders server side code just like getServerSideProps in which i can run my mongoose query?
Try this way in your api controller
const handler = nextConnect();
//Shop Schema
const Shop = mongoose.model('Shop',{
shopName: String,
id: String
});
//Post request handeler
handler.post(async (req, res) => {
var shop = new Shop({
shopName: req.body.name,
id:req.body.id
})
let data = await shop.save();
res.json({message: 'ok'});
})

findByIdAndUpdate not updating document on MongoDB

I am trying to create an Api that updates my MongoDB before sending a password reset email to the user using nodemailer. Everything works fine except the database update for some reason. I am using findByIdAndUpdate to do the update.
My api starts with
router.put('/forgot',[auth, [check('email', 'Please include a valid email').isEmail()]],async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email } = req.body;
try {
let user = await User.findOne({ email });
if (!user) {
return res.status(400).json({
errors: [
{
msg:
'That email addrss is not recognized. Please try again or register for a new account ',
},
],
});
}
var email_token = crypto.randomBytes(64).toString('hex');
const payload = {
id: user.id,
resetPasswordToken: email_token,
resetPasswordExpires: Date.now() + 3600000,
};
user = await User.findByIdAndUpdate(
user.id,
{ $set: payload },
{ new: true }
);
console.log(user);
res.json(user);
Thank you Joe and Mohammed, Well from Mohammed question i realized i did not define resetPasswordToken and resetPasswordExpires in the User Model. As soon as i did that every thing worked as magic. Thank you so much!

Mongoose not fetching data until I refresh the database connection

I am trying to re-fetch the data from MongoDB using mongoose whenever a user reloads the page. However, the old data stays there and the new data doesn't get fetched until I restart the server.
Here is the router:
router.post("/dashboard", (req, res) => {
const userId = req.body.userId;
User.findOne({ _id: userId }, (err, users) => {
if (err) {
console.log(err);
res.status(500).send();
} else {
router.get("/dashboard", (req, res, next) => {
const leagues = [users.leagues.premium, users.leagues.free];
if (err) return next(err);
res.status(200).send(leagues);
});
}
});
});
And here is the Actions (Redux):
export const fetchLeagues = userId => dispatch => {
axios.post("/api/leagues/dashboard", userId).then(
setTimeout(function() {
axios.get("/api/leagues/dashboard").then(leagues => {
dispatch({
type: GET_LEAGUES,
payload: leagues
});
});
}, 50)
);
};
The data must be fetched from a specific user, so that's why I am posting the user Id, then getting the data back. Not sure if this is the best way of doing this.
Just to clarify, I am using the MERN stack with redux and axios to execute this. I tried to use this: MongoDB does not refresh data automatically?, but I still can't get this thing to refresh/re-fetch the data when the router is called again. Thanks.
Doing a POST request then a GET request seems unnecessary here as you can just return the data in a single request.
The reason why the data is being persisted is because when you declare the router.get('/dashboard') route you are permanently hardcoding that route to have the values from the first request.
It's probably best to use a GET request, as that is what you are trying to do.
e.g.
router.get("/dashboard/:userId", (req, res) => {
const userId = req.params.userId;
User.findOne({ _id: userId }, (err, users) => {
if (err) {
console.log(err);
res.status(500).send();
} else {
const leagues = [users.leagues.premium, users.leagues.free];
if (err) return next(err);
res.status(200).send(leagues);
}
});
});
// Where userId is now a string
export const fetchLeagues = userId => dispatch => {
axios.get(`/api/leagues/dashboard/${userId}`).then(leagues => {
dispatch({
type: GET_LEAGUES,
payload: leagues
});
});
};

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

PRISMA: How to receive REST API post requests (non GraphQL)?

How to create one route for receiving non graphql post requests?
I have my graphql server, and want to receive some non graphql data on it.
const server = new GraphQLServer({ ... })
server.express.get('/route', async (req, res, done) => {
const params = req.body;
// do some actions with ctx..
})
How can we access to ctx.db.query or ctx.db.mutation from this route?
Thanks!
Related question: https://github.com/prisma/graphql-yoga/issues/482
https://www.prisma.io/forum/t/how-to-create-one-route-for-receiving-rest-api-post-requests/7239
You can use the same variable you passed in the context:
const { prisma } = require('./generated/prisma-client')
const { GraphQLServer } = require('graphql-yoga')
const server = new GraphQLServer({
typeDefs: './schema.graphql',
resolvers,
context: {
prisma,
},
})
server.express.get('/route', async (req, res, done) => {
const params = req.body;
const user = prisma.user({where: {id: params.id} })
res.send(user)
})