How to send data to MongoDB that is calculated after page loads? - javascript

I am using Node.js with Express and MongoDB.
I have a page, '/score' that calculates the user's score from a quiz taken on the previous page. The '/score' route is below:
app.get('/score', stormpath.getUser, function(req, res) {
var quiz = req.session.mostRecentQuiz;
db.collection('quizzes').find(quiz).toArray(function (err, docs) {
assert.equal(err, null);
var quiz;
docs.forEach(function (doc) {
quiz = doc.quiz;
});
res.render('score', {quiz: quiz});
});
db.collection('users').update({user: req.user.username}, { $set: {"mostRecentQuiz": quiz } }, function (err, result) {
if (err) throw err;
console.log(result);
} );
});
After getting the quiz answers from the DB, I use some client-side JavaScript on the /score page to calculate the user's score and then report it to the user. However, I would like to get that same score back to my MongoDB, but I am not sure how best to accomplish that.
Can I use AJAX to accomplish this, or would it be better to redirect to a new page?

If you're already using Express, the simplest way would be to define a route for updating the score. Then you can send the data to the server via AJAX.
In order to parse the request parameters install the body-parser module.
Server:
var bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.put('/score', stormpath.getUser, function (req, res) {
console.log(req.body); // there should be your received data
// save it to the database
db.collection('yourcollection').updateOne(
{}, // your query for updating the data in the wished field
function(err, results) {
if(err) { return res.json(err); };
return res.json(results);
});
});
Client - if you're using jQuery:
$.ajax({
url: '/score',
type: 'PUT',
contentType: 'application/json',
data: {'score':1000}, // put here your data to send it to the server
success: function(data){
console.log(data);
}
});
Some documentation:
MongoDB update: https://docs.mongodb.com/getting-started/node/update/
jQuery AJAX: https://api.jquery.com/jquery.ajax/

Related

How to send data from NodeJS server side to the JS client side, only when data is ready?

On my website, when the user clicks on a button, some user's data will be stored in a database and after that I want the server to send notification data to the Javascript frontend file to change the UI.
Right now, the Js file (index.js) receives data right after the website loads (always false). I want it to be received only when the data is ready on the server.
I searched a lot but couldn't find an answer to my problem?
I appreciate any help :)
server.js
var requestValidation = false;
app.post("/", function(req, res){
var name = req.body.personName;
var email = req.body.personEmail;
var collabTopic = req.body.collabTopic;
const newUser = new User({ //mongoDB schema
name: name,
email: email,
collabTopic: collabTopic
});
newUser.save(function(err){ //adding data to mongoDB
if(!err){
requestValidation = true;
}
});
});
app.get("/succ", function(req, res){
res.json(requestValidation);
});
index.js
const url = "http://localhost:3000/succ";
const getData = async (url) => {
try {
const response = await fetch(url);
const json = await response.json();
console.log(json);
} catch (error) {
console.log(error);
}
};
getData(url);
I'm not sure this is completely the answer you're looking for, but it's definitely a tool/feature to consider as you rework your approach.
app.post("/", async (req, res) => {
let result = await INSERT MONGODB UPDATE OR INSERT FUNCTION;
res.render("YOUR TEMPLATE", result);
});
You probably can't plug and play this, but when you finish a MongoDB operation, it returns a json object with some details on whether or not there was success. For example, a MongoDB insert operation returns something like this (stored in the variable result that I created)
{ "acknowledged" : true, "insertedId" : ObjectId("5fd989674e6b9ceb8665c57d") }
and then you can pass this value on as you wish.
Edit: This is what tkausl referred to in a comment.
Here is an example if you want to pass the content of a txt file to the client with express and jquery:
in express:
app.get('/get', (req, res) => {
fs.readFile('test.txt', (err, data) => {
if (err) throw err;
return res.json(JSON.parse(data));
})
})
jquery in client side:
$.getJSON( "http://localhost:3000/get", function( data ) {
geojsondata1 = JSON.stringify(data)
}
now you can do anything you want with the variable data

How can i list data from table in the database in a browser

I'm developing a web application using reactjs nodejs and mysql database.
I want to list the data created in a table i created in the database in the browser via a link(http://localhost:5000/api/v/companies) .What code should i write in a page created in reactsjs?
Here is the code in the file index.js the backend of the table i created :
const express = require("express");
const app = express();
const cors = require("cors");
const pe = require('parse-error');
const logger = require('morgan');
const database = require('./mysql');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({
extended: false,
limit: '800mb'
}));
// CORS
app.options("*", cors());
app.use(cors());
database.connect(function(err) {
if (err) throw err;
console.log("==> MySQL Connected Successfully!");
// The main page
app.get('/', function (req, res) {
res.json({
version: 'v1',
status: true
});
});
const stations = require('./routes/stations');
const companies = require('./routes/companies');
app.use('/api/v1', [stations, companies]);
});
app.listen(5000, () => {
console.log("Server is running on port 5000");
});
process.on('unhandledRejection', error => {
console.error('Uncaught Error', pe(error));
});
as well as other files created in the backend
const database = require('./../mysql');
/**
* List all companies
*/
const getAllCompanies = async function(req, res, next) {
try {
database.query('SELECT * FROM infos_stations.Companies', function (err, result, fields) {
if (err) throw err;
return res.status(200).json(result);
});
} catch (err) {
return res.status(500).send({
code: 500,
status: false,
data: "Internal Server Error"
});
}
};
module.exports = {
getAllCompanies,
};
In the reactjs application, you have to install any library for HTTP
requests. Axios is a Javascript library used to make HTTP requests
from node.js or XMLHttpRequests from the browser that also supports
the ES6 Promise.
In the backend, You have to create a route that accepts the HTTP request from
Frontend.
app.post('/getdata', function (req, res) {
// database queries etc.
//sending response(database result)at frontend.
}
In reactjs you can create an HTTP request on a button click or can create a
request on component renders using the UseEffect hook.
axios({
method: 'POST',
url: 'htttp//localhost/getdata',
responseType: 'stream'
})
.then(function (response) {
// response.data have all data of database.
//store response data in any reactjs state.
});
Use Map Function of state array in which you store a response that contains all database records. How to map lists How to render an array of objects in React?

How do I transfer data from a client-side form input to a server-side Nodejs script?

I'm trying to implement functionality which takes data from form inputs on the client-side and sends it to the server to be processed by my Nodejs backend.
I've got the server-side function working, but I'm unsure as to how I would go about sending the data from the client-side form to my backend server via the $.ajax GET request that submits the form.
The code I have so far:
Server side function:
app.get('/id', function(req,res) {
var query = "SELECT * FROM Control";
connection.query(query, function() {
console.log(query);
});
});
Client side function:
function select()
{
$.ajax({
type: 'get',
url: '/id',
success: function(data) {
var ceva = data;
console.log('#ceva');
},
error: function(err) {
console.log(err);
}
});
}
You want to use a POST request rather than a GET request. Doing so will allow you to send data along with the request that you can then use in your query on the server side and send the response back to your client. Like so:
Client Side
function select() {
var id = $('#My-ID-Input').val();
$.ajax({
type: 'post',
url: '/id',
data : {
id : id
},
success: function(data) {
var id = data.id;
$('#My-ID-Input').val(id);
},
error: function(err) {
console.log(err);
}
});
}
Server Side
app.post('/id', function(req, res) {
var data = req.body;
var id = data.id;
var query = "SELECT * FROM Control WHERE id=" + id;
connection.query(query, function(error, result) {
console.log(result);
res.send(result);
});
});
GOTCHA!
You need to make sure that you have the express bodyparser
middleware implemented into your server to ensure that the data sent
as the body of the post request is then parsed into an object literal
on the server side. In your server module/file, you'll need to include the following code, and ensure that you've npm install body-parser:
var bodyParser = require('body-parser');
app.use( bodyParser.json() );

AJAX call to/from MongoDB example for Node/Express?

This is to start with a very basic page: HTML Form, a button, and a div-box.
.click of the button would POST the Form data through AJAX.
The data is to be stored in MongoDB, and retrieved into the div-box without a page-refresh.
AJAX from index.html:
$(document).ready(function()
{
// handle button clicks
$('#buttonID').click(function() {
// make an ajax call
$.ajax({
dataType: 'jsonp',
jsonpCallback: '_wrapper',
data: $('#formID').serialize(),
type: 'POST',
url: "http://localhost:9999/start",
success: handleButtonResponse,
});
});
function handleButtonResponse(data)
{
// parse the json string
var jsonObject = JSON.parse(data);
$('#reponseID').append( jsonObject.message );
}
});
app.js:
var express = require('express'),
app = express();
cons = require('consolidate');
MongoClient = require('mongodb').MongoClient,
Server = require('mongodb').Server;
app.engine('html', cons.swig);
app.set('view engine', 'html');
app.set('views', __dirname + "/views");
var mongoclient = new MongoClient(new Server('localhost', 27017,
{ 'native_parser' : true }));
var db = mongoclient.db('database_name');
app.get('/', function (req, res) {
db.collection('collectionName').find({}, function (err, doc) {
res.render('index', doc);
});
response.writeHead(200, {"Content-Type:": "application/json"});
var submittedPost = {};
submittedPost['message'] = 'Proof that Node and Mongo are working..';
response.write( "_wrapper('" );
response.write( JSON.stringify(submittedPost) );
response.write( "')");
response.end();
});
app.get('*', function (req, res) {
res.send("404..", 404);
});
mongoclient.open(function (err, mongoclient) {
if (err) throw err
app.listen(9999);
console.log("Express server started on port 9999");
});
How/Where does the JSON connect to/from MongoDB?
Also, does Express require a templating engine, such as Consolidate? If so, how/where does that fit in?
Few suggestions
Regarding the ajax call in index.html
If your index.html is served by the same server, then please don't use a cross domain call. The url property in $.ajax could be a relative url like /start.
Also you can think of not using jsonp request.
the call could be like
$.ajax({
dataType: 'json',
data: $('#formID').serialize(),
type: 'POST',
url: "./start",
success: handleButtonResponse,
});
How/Where does the JSON connect to/from MongoDB?
In you ajax call you are requesting for ./start, So the same route should be made in your express server. like
app.get('/start', function (req, res) {
db.collection('collectionName').insert({req.data}, function (err, doc) {
//rest of code
});
});
does Express require a templating engine, such as Consolidate? If so, how/where does that fit in?
You have many options for templating like jade,ejs,hbs and so on.
If you use jade or any of them your html rendering code in express routes will get simplified.
without a templating engine
response.writeHead(200, {"Content-Type:": "application/json"});
var submittedPost = {};
submittedPost['message'] = 'Proof that Node and Mongo are working..';
response.write( "_wrapper('" );
response.write( JSON.stringify(submittedPost) );
response.write( "')");
response.end();
with a templating engine like jade (now pug)
var submittedPost = {};
submittedPost['message'] = 'Proof that Node and Mongo are working..';
response.json(submittedPost);
also with templating engines you can render templates with server side variables and you can access them inside your templates like
app.get('/mypage', function (req, res) {
res.render('mytemplate_page',{template_variable:some_variable});
});
and you can use template_variable inside the template for looping through or displaying.

Node.js ajax post to mongodb

I'm having problem with sending data from ajax client to nodejs and storing that data in a collection in mongodb.
Here's my client code:
testdata = {'test1':'test1', 'test2':'test2'}
for(i=0;i<2;i++){ // for testing purposes
$(".btn").click(function(){
$.ajax({
url: 'http://localhost:8000/1',
type: 'post',
dataType: 'json',
data: testdata ,
success: function(){
console.log(i);
}
});
});
}
And my node.js server post handler with express:
app.post('/1', function(req, res){
db.collection('test', function(err, collection){
var data = req.body;
collection.insert(data, function (err, result) {
if(!err){
console.log(result);
}else{
res.end();
}
});
});
});
Body parser middleware is on, mongo is on of course, but my test collection is not receiving any data. I have a sence that i'm missing something very obvious here. Thanks for the help, much appreciated.

Categories