How to display only searched results in the browser as response - node.js

I have a MongoDB collection that I search through by using a value from an input field using the $search operator and it works, when I console log the result it shows me only those documents that match the search, but I want them to be visible on the endpoint http://localhost:3001/search as well, but currently I get all the documents listed, how can I list the result of the search? I am trying with res.send(result); but it does not work. Here is my attempt:
// Requiring the dependencies
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
require('dotenv').config();
const mongoose = require('mongoose');
const PORT = process.env.PORT || 3001;
const BASE_URL = process.env.REACT_APP_BASE_URL;
const itemRoutes = express.Router();
let Comment = require('./comment.model');
app.use(cors());
app.use(bodyParser.json());
mongoose.connect(BASE_URL, { useNewUrlParser: true })
const connection = mongoose.connection;
connection.once('open', function () {
console.log('Connection to MongoDB established succesfully!');
});
let collection = connection.collection("posts_with_tags_test");
collection.createIndex(
{
postContent: 'text',
title: 'text'
}
);
itemRoutes.route('/search').post(async (req, res) => {
let result = await connection.collection("posts_with_tags_test").find({
$text: {
$search: req.body.queryString
}
}).toArray();
res.send(result);
console.log(result)
});
app.use('/search', itemRoutes);
app.listen(PORT, function () {
console.log('Server is running on' + ' ' + PORT);
})
and here is my input field:
import React, { Component } from "react";
import axios from "axios";
class Search extends Component {
getSearchQuery = () => {
const queryString = document.querySelector(
".search-input"
).value;
axios.post("http://localhost:3001/search", {
queryString: queryString,
});
console.log(queryString)
};
render() {
return (
<div>
<input
type="text"
className="search-input"
/>
<button type="submit" onClick={this.getSearchQuery}></button>
</div>
);
}
}
export default Search;

If you just access localhost:3001/search from a browser, it won't be visible because you aren't sending the data { queryString: "sample" } to be used in the query as req.body.queryString unless you're using Postman
If you're accessing it from frontend, in your React component's getSearchQuery, try using .then() on your axios.post() to receive the response from your backend
axios.post("http://localhost:3001/search", {
queryString: queryString,
}).then(response => {
console.log(response);
console.log(response.status);
console.log(response.data);
});

Related

Connecting front end to Mongodb

I am a beginner in coding, so please take it easy. I have built a database with node.js and mongodb. I am receiving sensor reads from an IoT device through a web sockets connection and am logging those entries to the database. This is my server code:
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
const expressWs = require('express-ws');
const Temperature = require('./models/temperature.model');
const Humidity = require('./models/humidity.model');
const Pressure = require('./models/pressure.model');
require('dotenv').config();
// This is to create the express server and what port it will be on
const app = express();
const port = process.env.PORT || 8080;
// This is the middleware, this will allow it to parse JSON because the server will be receiving JSON
app.use(cors());
app.use(express.json());
const wsInstance = expressWs(app);
// The uri is where the database is stored, start connection to database
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, { useNewUrlParser: true });
const connection = mongoose.connection;
connection.once('open', () => {
console.log("MongoDB database connection esablished successfully");
})
// Importing files
const temperatureRouter = require('./routes/temperature');
const humidityRouter = require('./routes/humidity');
const pressureRouter = require('./routes/pressure');
const router = express.Router();
// The connection to the web sockets where the sensor reads are received
app.ws('/sendData', (ws, req) => {
ws.on('message', function incoming(message) {
console.log(message);
ws.broadcast(message);
const tempData = message.slice(0, 5);
const humidData = message.slice(6, 11);
const pressureData = message.slice(12, 21);
const temperature = new Temperature({
temperature: tempData,
});
temperature.save();
const humidity = new Humidity({
humidity: humidData,
});
humidity.save();
const pressure = new Pressure({
pressure: pressureData,
});
pressure.save();
});
ws.broadcast = function broadcast(data) {
wsInstance.getWss().clients.forEach(function each(client) {
client.send(data);
});
};
})
app.use('/temp', temperatureRouter);
app.use('/humidity', humidityRouter);
app.use('/pressure', pressureRouter);
// This is what starts the server and listens on that port
app.listen(port, () => {
console.log(`Server is running on port: ${port}`);
});
Now I am trying to retrieve that data in my front end to display in a graph but do not understand why I am not receiving it. This is my front end code:
import React, { useEffect, useState } from 'react';
function DevExpressCharts() {
const [temperatures, setTemperatures] = useState([{
temperature: '',
date: ''
}])
useEffect(() => {
fetch('/temperatures').then(res => {
if(res.ok) {
return res.json()
}
}).then(jsonRes => setTemperatures(jsonRes))
})
return (
<div>
<h1>hello</h1>
{temperatures.map(temperature =>
<div>
<h1>{temperature.temperature}</h1>
</div>
)}
</div>
)
}
export default DevExpressCharts;
Routes:
const router = require('express').Router();
let Temperature = require('../models/temperature.model');
router.route('/temperatures').get((req, res) => {
Temperature.find()
.then(foundTemperature => res.json(foundTemperature))
.catch(err => res.status(400).json('Error: ' + err));
});
module.exports = router;
Models:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const temperatureSchema = new Schema({
temperature: { type: String, required: true },
}, {
timestamps: true,
});
const Temperature = mongoose.model('Temperature', temperatureSchema);
module.exports = Temperature;
Any help is greatly appreciated.
You should try changing this and check if this solves your problem or not.
Point-1:
Did u check if the api endpoint is giving proper responses in postman or any other api tester.
Point-2:
I noticed you are finding temperature collections from the database using .find().
Try doing it likewise:
const tempData=await Temperature.find();
if(tempData) return res.send(tempData);
Point-3:
Assuming your TemperatureRoute contains the router of the temperature. If so, then
your api should look like this: http://xyz.domain/temp/Temperature
Point-4:
Your fetch api should like this:
// get all collections
fetch("http://xyz.domain/temp/temperatures", {
"method": "GET"
})
.then(response => response.json())
.then(response => {
this.setState({
... //perform operations
})
})
.catch(err => { console.log(err);
});
I hope this solves your problem..

MERN - Express not receiving data from Post request

I am trying to send data from a search bar into my backend express server. However for some reason, it's not being updated.
import { useState } from "react";
import Button from 'react-bootstrap/Button';
const StockSearchBar = () => {
const [search, setSearch] = useState("Stock or Crypto Symbol");
const handleSearch = e => {
setSearch(e.target.value)
}
const handleClick = (e) => {
e.preventDefault()
console.log({search})
if (setSearch !== '') {
const searchResult = {search};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(searchResult)
};
fetch('http://localhost:3001/search', options)
.then(
() => {
console.log("Search entered");
}
);
// console.log(searchResult);
}
};
return (
<>
<div className="searchBar">
<label>Look for other Stocks or Cryptos: </label>
<input type='text' onChange={handleSearch} placeholder={search}/>
<Button variant="success" type="submit" onClick={handleClick}>Success</Button>
</div>
</>
);
};
export default StockSearchBar;
and here's the backend code
const request = require("request-promise");
const fs = require("fs");
const mongoose = require("mongoose");
const cheerio = require("cheerio");
const Stock = require("./model/Stock");
const express = require("express");
const cors = require("cors");
const cron = require('node-cron');
const app = express();
const bodyParser = require('body-parser');
//MIDDLEWARE
app.use(express.json({limit: '1mb' }));
app.use(cors());
app.use(express.static('backend'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}))
// DATABASE
app.get("/", (req, res) => {
Stock.find({}).then(
items => res.json(items)
).catch(err => console.log(err))
});
app.get("/search", (req, res) => {
console.log(req.body);
res.json({
search: req.body,
});
});
app.post("/search", (req, res) => {
console.log(req.body);
res.json({
search: req.body,
});
});
app.listen(3001, function () {
console.log("Server is running...");
});
In the front end - after clicking a button it console logs an object with the search entered.
However on the backend, all I get is json text like so:
{
"search": {}
}
It doesnt get updated even though the server is continually running. Thoughts?

How to fetch data from API in Node.js to a view in React.js

I tried to get data from my SQL Server Management Studio. I already made the the query inside API, so when I access those links using postman, it will retrieve data equals to the query inside those links. But when i want to show the data at page, it not comes out even though it already comes out at the console log. The error always changing, but never solved.
DbOperations Query
const config = require('./dbConfig');
const sql = require('mssql');
async function getRoles() {
try {
let pool = await sql.connect(/My Configuration Database/);
let products = await pool.request().query("SELECT [id],[division] FROM [FMLX_IME].[dbo].[ime.tbl_roles]");
return products.recordsets;
}
catch(error) {
console.log(error);
}
}
This is how I insert the function to API links
const express = require('express');
const cors = require('cors');
const app = express();
const bodyParser = require('bodyParser');
const Db = require('./dbOperations');
const router = express.Router();
const PORT = process.env.PORT || 3001;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.use('/api', router);
router.use((request, response, next) => {
console.log("============ MIDDLEWARE ============");
next();
});
router.route('/get-roles').get((request, response) => {
Db.getRoles().then(result => {
response.json(result);
console.log(result);
});
});
This how I tried to fetch the data, already tried so many ways but nothing works. Only success to retrieved the data if using API that already online or running, not from my localhost. (Already tried using axios too)
Class ManualTest extends React.Component {
constructor(props) {
super(props);
this.state = {
roles: [],
isLoaded: false
}
}
componentDidMount() {
fetch('http://localhost:3001/api/get-roles')
.then(result => console.log(result.json()))
.then(res => res.json())
.then(json => {
this.setState({
roles: json,
isLoaded: true
})
}).catch((err) => {
console.log(err);
});
}
render() {
const { isLoaded, roles } = this.state;
if(!isLoaded)
return <div>Loading...</div>
return (
<div className="App">
<ul>
{roles.map(role => (
<li key={role.id}>
ID: {role.id} || ROLE: {role.role}
</li>
))}
</ul>
</div>
);
}
}
export default ManualTest

POST endpoint created with Node.js not found

I have a database in Mlab that is MongoDB that has two collections and I am trying to make a POST endpoint to which I can post whatever a user has entered in a commentbox. However I am doing something wrong, because when I test my endpoint with Postman it says 404 that the endpoint is not found. Trying to post via the commentbox does not work too ofcourse. This is the url to my post endpoint:
https://astroecstatic-express.herokuapp.com/comments. However if I run this in the browser it displays an empty array, so how come I get a 404 error when trying to POST? What am I doing wrong and how can I make my POST endpoint? Here is my node.js server:
// Requiring the dependencies
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const PORT = process.env.PORT || 3001;
const itemRoutes = express.Router();
let Comment = require('./comment.model');
app.use(cors());
app.use(bodyParser.json());
mongoose.connect("mongodb://admin:SomeUSersecretpassword.mlab.com:41968/heroku_hc9xjmcl", { useNewUrlParser: true } )
const connection = mongoose.connection;
connection.once('open', function() {
console.log('Connection to MongoDB established succesfully!');
});
// Serve static assets
if(process.env.NODE_ENV === 'production') {
app.use(express.static('build'));
}
itemRoutes.route('/').get( async (req, res) => {
let collection = connection.collection("posts");
let response = await collection.find({})
.toArray();
res.send(response);
});
itemRoutes.route('/comments').get( async (req, res) => {
let collection = connection.collection("comments");
let response = await collection.find({})
.toArray();
res.send(response);
});
itemRoutes.route('/comments')
.post((req, res) => {
res.setHeader('Content-Type', 'application/json');
let comment = new Comment(req.body);
comment.save()
.then(comment => {
res.status(200).json({comment})
})
.catch(err => {
res.status(400).send('failed')
})
});
app.use('/', itemRoutes);
app.use('/comments', itemRoutes);
app.listen(PORT, function() {
console.log('Server is running on' + ' ' + PORT);
})
and my post component:
import React, { Component } from 'react';
import axios from 'axios';
class CommentBox extends Component {
constructor(props) {
super(props);
this.path = window.location.href;
this.postId = this.path.split("/").slice(-1)[0];
}
state = {
userComments: []
}
componentDidMount() {
const fetchPosts = async () => {
const res = await axios.get('https://astroecstatic-express.herokuapp.com/comments');
this.setState({...this.state, userComments: res.data})
};
fetchPosts();
}
getCommentData = (res) => {
let today = new Date();
let dd = String(today.getDate()).padStart(2, '0');
let mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
let yyyy = today.getFullYear();
today = mm + '/' + dd + '/' + yyyy;
const commentContent = document.querySelector(".comment-box-container__div-comment-box").textContent;
axios.post('https://astroecstatic-express.herokuapp.com/comments', {title: commentContent, date: today, commentId: this.postId })
window.location.reload();
}
render() {
let currentPostComments = this.state.userComments.filter((item) => {
return item.commentId === this.postId
})
return(
<div className="comment-box-container">
<div className="comment-box-container__div">
<button className="comment-box-container__post-comment-btn" onClick={this.getCommentData}> Post Comment</button>
<div className="comment-box-container__div-comment-box" contentEditable="true"></div>
</div>
<div className="comment-box-container__show-coments-section">
{currentPostComments.map(comment =>
<section>
<h3>{comment.date}</h3>
{comment.title}
</section>
)}
</div>
</div>
)
}
}
export default CommentBox;
Here's a simple way to create both a .get() and a .post() route for /comments on a router:
itemRoutes.get("/comments", function(req, res, next) {
// code here
});
itemRoutes.post("/comments", function(req, res, next) {
// code here
});
app.use(itemRoutes);
You can also use .route() instead like this:
itemRoutes.route("/comments").get(function(req, res, next) {
// code here
}).post(function(req, res, next) {
// code here
});
app.use(itemRoutes);
And, you don't even really have a compelling case for using a router for these two routes. You could also just do:
app.get("/comments", ...);
app.post("/comments", ...);
Or
app.route("/comments")
.get(...)
.post(...);
And, not even use a router for just two top level routes.

React to pull SQL data from server

I figured out how to make a request to SQL server and post as JSON on the server side. I'm wondering how I can pull that data into the react side.
Server.js:
let pullTable = require('./actions/pullTable.js');
var express = require('express');
var app = express();
app.get('/', async (req, res, next) => {
try {
const result = await pullTable.pullTable();
return res.status(200).json(result);
} catch (error) {
next(error);
}
});
app.listen(5000, () => {console.log('Server is running..')});
SQL Request - pullTable.js:
var sql = require("mssql");
var express = require('express');
var app = express();
// config for your database
var config = {
user: 'user',
password: 'pass',
server: 'localhost',
database: 'Master'
};
const pullTable = async () => {
try {
const pool = await sql.connect(config);
const sqlQuery = 'SELECT * FROM Persons';
const result = await pool.request().query(sqlQuery);
return result.recordset;
} catch (err) {
throw err;
}
};
exports.pullTable = pullTable;
The code works fine up to here. I look at port 5000 and can see the JSON data being displayed from my server. Just not sure how to get this into React. This is my attempt at the react side (not including the App.js file - don't need help with that):
getData.js:
import React, { Component } from 'react';
class getData extends Component {
constructor(){
super();
this.state={
data:[],
}
}
componentDidMount(){
fetch('http://localhost:5000')
.then((Response)=>Response.json())
.then((findresponse)=>
{
this.setState({
data:findresponse,
});
});
}
render() {
return (
<div>
{
this.state.data.map((dynamicData)=>
<div>
<span>{dynamicData.LastName} </span>
<span>{dynamicData.FirstName}</span>
</div>
)
}
</div>
);
}
}
export default getData;
Just looking to display the first and last name of people in that SQL table.
#Shawn Yap pointed me in the right direction. Basically had to include the Access-Control-Allow-Origin header on the server script:
let pullTable = require('./actions/pullTable.js');
var express = require('express');
var app = express();
app.get('/', async (req, res, next) => {
try {
res.set('Access-Control-Allow-Origin', '*');
const result = await pullTable.pullTable();
return res.status(200).json(result);
} catch (error) {
next(error);
}
});
app.listen(5000, () => {console.log('Server is running..')});
Not sure if this even good code, but it's working.

Resources