Fetch Data from mongoDb using ReactJs and node - node.js

I have a mern project where i want to fetch data from mongodb in my reactjs.
I have gone through sevral previous question but it didn't help!
i have successfully fetched all data all together
But i want to fetch olny specific data ilke email. How can i do that?
Admin.js(frontend)
import React from 'react';
import axios from 'axios';
class Admin extends React.Component {
state = {
phone: '',
email: '',
posts: []
};
// componentDidMount = () => {
// this.getBlogPost();
// };
hello = () => {
axios.get('/getuser')
.then((response) => {
const data = response.data;
this.setState({ posts: data });
console.log(data);
})
.catch(() => {
alert('Error retrieving data!!!');
});
}
displayBlogPost = (posts) => {
if (!posts.length) return null;
return posts.map((post, index) => (
<div key={index} className="blog-post__display">
<h3>{post.phone}</h3>
<p>{post.email}</p>
</div>
));
};
render() {
return (
<>
<h1>
<button onClick={this.hello} class="btn btn-danger">click here to get data</button>
</h1>
<div className="blog-">
{this.displayBlogPost(this.state.posts)}
<table>
<tr>
<th>email</th>
<th>phone</th>
</tr>
<tr>
<td>rah098755#gmail.com</td>
<td>8340251638</td>
</tr>
<tr>
<td>kumar_rahulkkcs#yahoo.com</td>
<td>78750251638</td>
</tr>
<tr>
<td>anita#gmail.com</td>
<td>9652251638</td>
</tr>
</table>
</div>
</>
)
}
}
export default Admin;
i am getting data in my browser like this---
How can i show olny specific data
thankyou

So I am going to assume you have an Express App running with endpoints you are calling from this front-end code given the /get-user endpoint. The endpoint returns all of the user data for one or more users depending on how you set it up. In order to get a list emails for users, you will need something to distinguish your API call to the Express App that you want only the emails for the users, and not the full user object. There are a lot of ways to make this distinction, but another route is probably the best option to adhere to REST in some way. Below is a possible example:
Express Endpoint
app.get('/users/email', (req, res) => {
Call MongoDB and filter the user list to just email for response
}
REACT Call
emails = () => {
axios.get('/users/email')
.then((response) => {
const data = response.data;
this.setState({ emails: data });
console.log(data);
})
.catch(() => {
alert('Error retrieving data!!!');
});
}
It is in the Express app that you should filter and ideally sort data for the front-end app to consume. Otherwise you risk sending too much data to the front-end or sending sensitive data by accident. Take a look at the below link for a bit more robust example.
https://codingthesmartway.com/the-mern-stack-tutorial-building-a-react-crud-application-from-start-to-finish-part-1/

Related

Show detail Button in table not working(instead pages gets reload) and Not getting all the data properly of the table from mongodb

As I click on the Show detail button I should get an alert/more info of the user but instead of that the page gets reload. Basically on 'show details' button the 'OnClick' function is not getting executed.
Why am I getting no enteries found after clicking on 'show details'
Fetching data from Database and setting it in 'clientTable' variable:
React.useEffect(()=>{
window.onload=()=>{
const datatablesSimple = document.getElementById('datatablesSimple');
if (datatablesSimple) {
new DataTable(datatablesSimple);
}
const fetchClients = async ()=>{
const res = await axios.get("/users")
setClientTable((clientTable)=>{return clientTable=res.data;})
console.log(clientTable)
}
fetchClients()
}
},[]);
Nodejs code for fetching all the Clients
router.get("/", async(req, res) => {
try{
const allclients = await User.find();
res.status(200).json(allclients);
}catch(err){
res.status(500).json(err);
}
});
HTML code of rendering the table in frontend:
<tbody>
{clientTable.map((User, index)=>(<>
<tr key={index}>
<td>
<Link to="/details" state={User}
style={{textDecoration:'none',
color:'black'}} > {User.username}
</Link>
</td>
<td>{User.email}</td>
<td>{User.dob}</td>
<td>{User.city}</td>
<td>{User.services}</td>
<td><button onClick={handleRowClick}> show details</button></td>
</tr>
</>
))}
</tbody>
handleRowClick method implementation:
const handleRowClick = (e) => {
e.preventDefault();
alert("Hello")
//setShowPopup(true);
}

React JS Modal Show White Blank Screen

I have a data called person in JSON format getting from API in the file User.js:
const [person, setPerson] = useState([]);
const url = "http://localhost:8080/api/persons";
useEffect(() => {
axios.get(url).then((response) => {
setPerson(response.data);
});
}, [url]);
In another file called UpdatePersonForm.js I'm trying to show that data in popup windows after clicking a button.
export const UpdatePersonForm= ({ person, personEditOnSubmit }) => {
return (
<div>
{person.map((item) => (
<tr>
<td>{item.name}</td>
</tr>
))}
</div>
}
then it shows a white blank screen again. If I called an API directly from UpdatePersonForm.js then it works fine. For example:
export const UpdatePersonForm= ({ personEditOnSubmit }) => {
const [person, setPerson] = useState([]);
const url = "http://localhost:8080/api/persons";
useEffect(() => {
axios.get(url).then((response) => {
setPerson(response.data);
});
}, [url]);
return (
<div>
{person.map((item) => (
<tr>
<td>{item.name}</td>
</tr>
))}
</div>
}
However, if I get data from the parent file like the above then I got wrong.
You initialize the person variable with const [person, setPerson] = useState(""); which means that on first render person will be a string and strings do not have a .map method.
Use const [person, setPerson] = useState([]); and you should be fine.
Since you expect it to be an array after the JSON is fetched, you should also initialize it to one.

useState data not working with .map function

I have this app that fetches the blog posts from an API. The API response with blog posts and I'm getting those blog posts to GetBlogState state. When I'm looping through GetBlogState using the .map I am getting the following error.
The following is the code that I'm currently working with.
import React, { useState, useEffect } from 'react';
import Head from 'next/head'
import axios from 'axios'
import HeaderComponent from '../components/HeaderComponent';
export default function Blog(){
const [GetBlogState, SetBlogState] = useState([]);
useEffect(() => {
axios.get('http://localhost:4000/blog').then(res => {
SetBlogState(res)
}).catch(errr => {
console.log(err)
})
}, []);
return (
<div className="MyApp">
{ GetBlogState.map(item => (
<div className="h-68">
<img className="w-full" alt="post" src='post.jpg' />
<div className="mt-3 mb-2 text-xs">May 10, 2018</div>
<h2 className="font-bold mb-5 text-xl">{ item.Title } </h2>
<p>{item.content}</p>
</div>
))}
</div>
)
}
I think you should check the output what you are getting in res from axios.
you are setting response object in state which is wrong.
You should do
useEffect(() => {
axios.get('http://localhost:4000/blog').then(res => {
//// console.log(res) Check whats returning in res \\\
SetBlogState(res.data)
}).catch(errr => {
console.log(err)
})
}, []);
Axios' response schema put server response in data. Hence set state like SetBlogState(res.data)

Pass parameter in React Url to get relative data

I created a express api where when we pass parameter to url say localhost:8000/data?music=rock it gives me data associated with it and if i pass say localhost:8000/data?music=rap and gives me data associated with it....P.S. there are many genre of music classical and so on and data associated with it.
Express api:: connected to mongoose where I scraped a data and stored in mongodb from where it feteches the data
app.get('/data'.(res,req)=>{
count music = req.query.music
collection.find({"music":music},(err,result)=>{
if(err):
return res.status(500).send(err);
}
else{
console.log(docs);
res.send(docs);
}
});
});
React JS::::
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {apiResponse:"",genre:""};
}
async callAPI(e) {
console.log(e.target.value);
const url = `http://localhost:8000/data?music=${e.target.value}`;
const response = await fetch(url);
console.log(response);
const textResponse = response.text();
console.log(textResponse);
this.setState({apiResponse:textResponse});
}
render() {
const {apiResponse} = this.state;
console.log(apiResponse);
return (
<>
<select name="continent" id="continent" onClick={e=>this.callAPI(e)}>
<option value=" ">--Please choose an option--</option>
<option value="Europe">Europe</option>
<option value="North America">North America</option>
</select>
{apiResponse && <h1>{apiResponse.title}</h1>}
</>
);
}
}
export default App;
Now i connected my express api with react but as you can see i have provided static path as
fetch("http://localhost:8000/data?music=Rock")
to get the data associated with rock music.
But I want react to fetch different genre of music dynamically from API without using a static path to fetch data. like react port:: localhost:3000/music=rock and it gives me data of rock music or classical and it gives me data of that.
Can anyone from community guide me on what method can be used or any article? Will be really appreciated. Cheers!!
You can use the select element to trigger an onChange event to fetch data from the user. Here, I replaced the url with template literals. After the fetch is complete and apiResponse is set, you can then map the data in the return block.
Here is a working sandbox.
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = { apiResponse: "", genre: "" };
}
async callAPI(e) {
console.log(e.target.value);
const url = `http://localhost:8000/data?music=${e.target.value}`;
const response = await fetch(url);
console.log(response);
const textResponse = response.text();
console.log(textResponse);
this.setState({ apiResponse: textResponse });
}
render() {
return (
<>
<select name="genre" id="genre" onChange={e => this.callAPI(e)}>
<option value="">--Please choose an option--</option>
<option value="Rap">Rap</option>
<option value="Rock">Rock</option>
</select>
</>
);
}
}
export default App;
You can use axis for the request and set the params, in this case, the music
axios.get('http://localhost:8000/data', {
params: {
music: 'rap'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.finally(function () {
// always executed
});
You can read more about axis here
You can add a controlled input field for music and use this.state.music in the fetch URL
https://reactjs.org/docs/forms.html#controlled-components

React: How to update the DOM with API results

My goal is to take the response from the Google API perspective and display the value into a div within the DOM.
Following a tutorial : https://medium.com/swlh/combat-toxicity-online-with-the-perspective-api-and-react-f090f1727374
Form is completed and works. I can see my response in the console. I can even store the response into an object, array, or simply extract the values.
The issue is I am struggling to write the values to the DOM even though I have it saved..
In my class is where I handle all the API work
class App extends React.Component {
handleSubmit = comment => {
axios
.post(PERSPECTIVE_API_URL, {
comment: {
text: comment
},
languages: ["en"],
requestedAttributes: {
TOXICITY: {},
INSULT: {},
FLIRTATION: {},
THREAT: {}
}
})
.then(res => {
myResponse= res.data; //redundant
apiResponse.push(myResponse);//pushed api response into an object array
console.log(res.data); //json response
console.log(apiResponse);
PrintRes(); //save the values for the API for later use
})
.catch(() => {
// The perspective request failed, put some defensive logic here!
});
};
render() {
const {flirty,insulting,threatening,toxic}=this.props
console.log(flirty); //returns undefined, makes sense upon initialization but does not update after PrintRes()
return (
<div className="App">
<h1>Please leave a comment </h1>
<CommentForm onSubmit={this.handleSubmit} />
</div>
);
}
}
When I receive a response from the API I use my own function to store the data, for use later, the intention being to write the results into a div for my page
export const PrintRes=() =>{
// apiResponse.forEach(parseToxins);
// myResponse=JSON.stringify(myResponse);
for (var i = 0; i < apiResponse.length; i++) {
a=apiResponse[i].attributeScores.FLIRTATION.summaryScore.value;
b=apiResponse[i].attributeScores.INSULT.summaryScore.value;
c=apiResponse[i].attributeScores.THREAT.summaryScore.value;
d=apiResponse[i].attributeScores.TOXICITY.summaryScore.value;
}
console.log("hell0");//did this function run
// render(){ cant enclose the return in the render() because I get an error on the { , not sure why
return(
<section>
<div>
<p>
Your comment is:
Flirty: {flirty}
</p>
</div>
<div>
<p>
Your comment is:
insulting: {insulting}
</p>
</div>
<div>
<p>
Your comment is:
threatening: {threatening}
</p>
</div>
<div>
<p>
Your comment is:
toxic: {toxic}
</p>
</div>
</section>
);
}
Variables and imports at the top
import React from "react";
//needed to make a POST request to the API
import axios from "axios";
import CommentForm from "../components/CommentForm";
var myResponse;
var apiResponse= [];
let a,b,c,d;
let moods = {
flirty: a,
insulting:b,
threatening:c,
toxic:d
}
If I understand correctly You need to create a state where you store data from api.
States in react works like realtime stores to refresh DOM when something change. this is an example to use it
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
apiData: undefined
};
}
fetchData() {
this.setState({
apiData: "Set result"
});
}
render() {
const { apiData } = this.state;
return (
<div>
<button onClick={this.fetchData.bind(this)}>FetchData</button>
<h3>Result</h3>
<p>{apiData || "Nothing yet"}</p>
</div>
);
}
}
you can check it here: https://codesandbox.io/s/suspicious-cloud-l1m4x
For more info about states in react look at this:
https://es.reactjs.org/docs/react-component.html#setstate

Resources