Reputation: 111
I'm trying to build a search bar with a react frontend and node backend, that will let me search a customer ID from a mongoDB collection, then pull all of the data from a single document down from within the collection and display it on my react app.
Currently, I am just trying to get to get the single document bit to work, if this is possible. At the moment, it pulls down the entire collection.
My current Node code:
Search router
const express = require('express');
const app = express();
const tfiPaintCodesRouter = express.Router();
const PaintInfoSchema = require('../models/PaintInfoSchema.js');
tfiPaintCodesRouter.route('/get').get(function (req, res) {
const tfipaintcode = new PaintInfoSchema(req.body);
console.log(req.body)
tfipaintcode.save()
.then(tfipaintcode => {
res.json('Got data!!');
})
.catch(err => {
res.status(400).send("unable to get data");
console.log('CustomerID is required', err.res);
});
});
tfiPaintCodesRouter.route('/').get(function (req, res) {
PaintInfoSchema.find(function (err, tfipaintcodes){
if(err){
console.log('this is an error!', err.res);
}
else {
res.json(tfipaintcodes);
}
});
});
module.exports = tfiPaintCodesRouter;
Mongo schema using mongoose.
const mongoose = require('mongoose')
var uniqueValidator = require('mongoose-unique-validator');
const Schema = mongoose.Schema;
// Create schema
const PaintInfoSchema = new Schema({
customerID: {
required: true,
index: true,
unique: true,
type: String
},
companyName: {
index: true,
type: String
},
curtainCodes: {
index: true,
type: String
},
sinageCodes: {
index: true,
type: String
},
Notes: {
index: true,
type: String
},
Method: {
index: true,
type: String
},
},{
collection: 'tfiPaintCodes'
});
PaintInfoSchema.plugin(uniqueValidator);
module.exports = mongoose.model('PaintInfoSchema', PaintInfoSchema)
My current react code is:
import React from 'react';
import { Form, FormGroup, Input, Container, Row, Col } from 'reactstrap';
import './Search.css'
import axios from 'axios'
class Search extends React.Component {
constructor(props) {
super(props)
this.state = {
searchInfo: []
};
}
handleInputChange = (event) => {
event.preventDefault();
const { value } = event.target;
console.log('Value', value)
this.setState({
query: value
});
this.search(value);
};
search = query => {
axios.get('http://localhost:3001/getData')
.then(res =>{
const searchInfo = (res.data || []).map(obj => ({
company: obj.companyName,
sinage: obj.sinageCodes,
method: obj.Method,
notes: obj.Notes}));
this.setState({ searchInfo });
})
};
componentDidMount() {
this.search("");
}
render() {
return(
<Container>
<Form>
<Row>
<Col md={{ size: 6 ,offset: 3}}>
<FormGroup className="SearchBar">
<Input onChange={this.handleInputChange} type="search" name="search" id="exampleSearch" placeholder="search" />
</FormGroup>
</Col>
</Row>
</Form>
<ul>
{this.state.searchInfo.map(function(searchInfo, index){
return (
<div key={index}>
<h1>NAME: {searchInfo.company}</h1>
<p>{searchInfo.sinage}</p>
<p>{searchInfo.method}</p>
<p>{searchInfo.notes}</p>
</div>
)
}
)}
</ul>
</Container>
);
}
}
export default Search
The code above queries mongodb, then pulls down all of the data stored in my collection, here is an image of the returned data.
Data displayed in frontend
But i want to know if it is possible to just pull down one document in that collection, so it would just display one Name: and then the other 4 bits of data.
I have the data stored in Mlab, here is a screenshot of the documents stored in my collection.
Is this possible? Thanks!
Upvotes: 2
Views: 6947
Reputation: 196
The best way is to pull only one document from the DB (if you don't need more in your case).
Mongoose, as any other ORM/ODM, gives you those options:
https://mongoosejs.com/docs/api.html#model_Model.findOne
With FindOne
you can search for documents but get only one (aka. "the first found") document back.
If you need a fixed number of returned documents, you can use limit(10)
to, for example, return only 10 documents.
Though it appears to me that your code-snippets don't show the exact segment where do the query in Mongoose, otherwise we could have shown you what to do in your own example.
Upvotes: 1