Pass parameter in React Url to get relative data - node.js

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

Related

React - How to update my component when there is a change on the server

I want to reload the page when a put request is successful but it never reloads the page. what is the problem
async function saveEdit() {
await Axios.put('http://localhost:5000/edit', {id: id, newTitle: title, newDescription: description, newImageURL: imageURL});
window.location.reload();
}
the request works but the reload() line doesn't seem to work. or is there a better way to do this?
A simple implementation of useState() hook in react
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [data, setData] = useState(null);
async function saveEdit(id, title, description, imageURL) {
// Make sure that your request responds back with the relevant and fresh batch of data after the update
var res = await Axios.put('http://localhost:5000/edit', {id: id, newTitle: title, newDescription: description, newImageURL: imageURL});
//window.location.href = window.location.href;
var data = res.data;
setData(data)
}
return (
<div>
{data?.map(d=>{
// How you want to processes your data object.
return <h1>d.title</h1>
})}
<button onClick={()=>saveEdit(1,"Mytitle","description","test Url")}> Update </button>
</div>
);
}
For more information in react hooks refer here.

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

the results of my api (back end part) is not displayed in the front end part using reactjs

I am a beginner in nodejs and reactjs and I am developing a simple application. I am now in the front part, I installed all the necessary packages and modules. I launched my front part but nothing is displayed here is a screenshot of the result obtained. thank you in advance
And here a part of my code in reactjs
import React from 'react';
import {connect} from 'react-redux';
import {fetchVideos} from '../actions/videoActions';
var listVideos
class videos extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() { this.props.fetchVideos(); }
render() {
if (this.props.data) {
listVideos = this.props.videos.map(video =>
<li key={video._id}>
{video.titre}
</li>
);
}
return (
<div>
<center><h1>All videos </h1></center>
{listVideos}
</div>
)
}
}
const mapStateToProps = (state, ownProps) => {
return {
clients : state.clients,
};
}
const mapDispatchToProps = (dispatch) => {
return {
fetchVideos :()=> dispatch(fetchVideos())
};
}
export default connect(mapStateToProps, mapDispatchToProps)(videos);
If you are using redux, probably you will need to map the videos in the mapStateToProps method
// ...
componentDidMount() { this.props.fetchVideos(); }
// ...
const mapStateToProps = (state, ownProps) => {
return {
clients : state.clients,
videos: state.videos // HERE
};
}
Note the state.videos param is got from the reducer.
In your component, you are trying to read videos from its props. However, as Luiz mentioned, your mapStateToProps is only mapping the clients state variable to your component. mapStateToProps is the logic that binds redux state with your component props. So, assuming that you have set the videos object on your state (via reducers) and adding the videos mapping on the mapStateToProps you should get said data on your component props.

Losing currentUser when App component refreshes?

I am currently working on a simple web app using React, Node.js, passport-google-oauth20.
For some reason, whenever the application re-mounts, I lose the currentUser state. It's as if req.user is just lost.
The way it works is I first fetch the current user when the application mounts and set this.state.currentUser to the results. The issue is when the page refreshes. The component re-mounts and I lose the user. I tried logging the user and receive null.
Hopefully I explained this well enough... here is the code:
App component:
import React from 'react';
import List from './List';
import ListForm from './ListForm';
import * as helpers from '../helpers';
class App extends React.Component{
state = {
currentUser: '',
}
componentDidMount() {
helpers.fetchUser()
.then(data => {
this.setState({
currentUser: data
});
});
}
onSubmit = (id, item) => {
helpers.addItem(id, item);
}
render() {
return (
<div className="container">
<List
currentUser={this.state.currentUser}
onSubmit={this.onSubmit}
/>
</div>
);
}
};
export default App;
Helpers:
import axios from 'axios';
export const fetchUser = async () => {
const resp = await axios.get('/api/current_user');
return resp.data;
}
export const addItem = (id, newItem) => {
axios.post("/api/" + id + "/addItem", newItem);
}

Display response object from GET request on backend in react component

I am still figuring React out and have a question. I want to display some data that I am getting back from my mLab database. When I make the request in Postman to test request i get back the object full of data and now I want to display that data in my component.
Backend/server.js:
//this is tested and works in postman
app.get('/logs', function(req, res) {
user: req.user;
res.json();
});
React action:
export const GET_DATA_SUCCESS = 'GET_DATA_SUCCESS';
export const GET_DATA_TRIGGERED = 'GET_DATA_TRIGGERED';
export const GET_DATA_FAILURE = 'GET_DATA_FAILURE';
export function getData() {
const promise = fetch('http://localhost:8080/logs');
return {
onRequest: GET_DATA_TRIGGERED,
onSuccess: GET_DATA_SUCCESS,
onFailure: GET_DATA_FAILURE,
promise,
};
}
Component where I want to display:
import React from 'react';
import {Router, Route, Link, Redirect, withRouter} from 'react-router-dom';
import { getData } from '../actions/memory';
import { connect } from 'react-redux';
export class oldMemory extends React.Component {
oldSearch(e) {
e.preventDefault();
this.props.getData();
}
render() {
return(
<div className="old-info">
<Link to="/main"><h3 className="title-journey">Travel Journal</h3></Link>
<h4>Retrieve a Memory</h4>
<p className="get-info">Look back on an old place you have visited and
reminisce.</p>
<input className="search" type="text" name="search" placeholder="Search"
/>
<button onClick={this.oldSearch.bind(this)}>Get</button>
// would like data to show up here
</div>
)
}
}
export default connect(null, { getData })(oldMemory)
I would use a state to store the data and set the state after the getData promise is resolved. Then, in the render method, i map the state data to div elements and display them in the the component.
// I assume your result of get Data is an array of
// objects {id: number,date: string, memory: string}
// and that getData is a promise
class OldMemory extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
}
}
oldSearch = (e) => {
e.preventDefault();
this.props.getData().then(data => {
// if data is null, or undefined set it to an empty array
this.setState({ data: data || [] });
})
}
render() {
// build data to div elements for display
const memories = this.state.data.map(d => <div>{d.date} - {d.memory}</div>)
return(
<div className="old-info">
<Link to="/main"><h3 className="title-journey">Travel Journal</h3></Link>
<h4>Retrieve a Memory</h4>
<p className="get-info">Look back on an old place you have visited and
reminisce.</p>
<input className="search" type="text" name="search" placeholder="Search"
/>
<button onClick={this.oldSearch}>Get</button>
// would like data to show up here
<div id="display-data">
{ memories }
</div>
</div>
</div>
);
}
}
export default connect(null, { getData })(OldMemory)

Resources