Submit Data in mongoDB - 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'});
})

Related

How to send an object via fetch() to a dynamic api route in Next.js [duplicate]

This question already has answers here:
POST Request with Fetch API?
(7 answers)
Closed last year.
I am having trouble sending an object to my dynamic api route in Next. Sending a regular string works fine and I am able to update my MongoDB without issue. When sending the object though the request data just shows up as [object Object].
This is the current code snippet:
Client Side
let bookData = {
title: data[i].title,
author: data[i].author,
date: data[i].date,
isbn: data[i].isbn,
description: data[i].description,
image: data[i].image
}
fetch(`/api/db/saveBook/${bookData}`);
API Route: /pages/api/db/saveBook/[book].js
import { MongoClient } from "mongodb";
export default async function handler(req, res) {
const book = req.query;
const client = await MongoClient.connect(process.env.MONGODB_URI);
const db = client.db();
const collection = db.collection('books');
const addBook = await collection.insertOne(book);
client.close();
res.json(addBook);
}
consider 2 steps first send data through post request, then specify the content type through fetch request. see the example:
const req = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: formData.get("email"),
password: formData.get("password"),
}),
});
So this was a case of me misunderstanding when to use Dynamic API routes within next. Below is the correct implementation of what I was trying to do, which is just a basic POST request using fetch as others mentioned here.
Client:
// Store book data to be sent to API route
let bookData = {
title: data[i].title,
author: data[i].author,
date: data[i].date,
isbn: data[i].isbn,
description: data[i].description,
image: data[i].image
}
// Send the book data to the backend API to be saved
fetch('/api/db/saveBook',
{
method: 'POST',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(bookData),
}
);
API Route:
import { MongoClient } from "mongodb";
export default async function handler(req, res) {
const book = req.body;
const client = await MongoClient.connect(process.env.MONGODB_URI);
const db = client.db();
const collection = db.collection('books');
const addBook = await collection.insertOne(book);
client.close();
res.json(addBook);
}

How can I insert data to MongoDB from Next JS page without api?

Hi I was trying to post/insert data from next js page to mongodb. I want to learn CRUD with out any api implementations. I was able to get data with getServerSidePropsbut I can't post any data to mongodb. I am using next-os's with-mongodb example.
const [username, setUsername] = useState();
const handleChangeUsername = (event) => {
setUsername(e.target.value);
event.preventDefault();
};
const handleSubmit = async (event) => {
console.log(username);
if (await db.collection("users").insertOne({username:})) {
console.log("done");
event.preventDefault();
}
event.preventDefault();
};

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)
})