Pass data from Vue front end to Node/Express backend - node.js

I want a user to be able to enter a city into a text input at the '/' route. Once that is submitted, id like to redirect to '/result' and show the info. The only way I can get '/result' to show what I want is if I hard code a city in the back end. How do I eliminate this?
GET request
app.get('/result', (req, res) => {
let city = 'Portland';
let url = `${process.env.BASEURL}${city}&units=imperial&APPID=${process.env.API_KEY}`;
axios.get(url)
.then(response => { res.json(response.data) })
.catch(error => {
return res.status(500).json({
success: false,
message: error.message
})
});
});
Service file that passes data from backend API
import axios from 'axios';
const url = "http://localhost:5000/result";
class WeatherService {
static getWeather() {
return new Promise((resolve, reject) => {
axios.get(url).then((res) => {
try {
resolve(res.data);
} catch (error) {
reject(error);
}
})
})
}
}
export default WeatherService;
Front end
<template>
<div>
<p class="error" v-if="error">{{ error }}</p>
<i class="fa fa-times close-icon none"></i>
<main>
<div class="location none">
<div class="city">{{ weather.name }}</div>
<div class="long-lat">{{ weather.coord.lon }}, {{ weather.coord.lat }}</div>
<div class="date">-, -:- pm</div>
</div>
<div class="main-content none">
<div class="tempIcon">
<div class="condition-icon"></div>
<div class="temp">{{ weather.main.temp }}<span>°</span></div>
</div>
<div class="weather">{{ weather.weather[0].main }}</div>
<div class="hi-low">{{ weather.main.temp_max }}° / {{ weather.main.temp_minl }}° <span></span>Feels like {{ weather.main.feels_like }}°</div>
</div>
</main>
<section class="details">
<div class="humidity none">
<i class="fa fa-tint"></i>
<h5>Humidity</h5>
<p class="humidity-value">{{ weather.main.humidity }}%</p>
</div>
<div class="pressure none">
<i class="fa fa-tachometer"></i>
<h5>Pressure</h5>
<p class="pressure-value">{{ weather.main.pressure }} hPa</p>
</div>
<div class="wind none">
<i class="fa fa-wind"></i>
<h5>Wind</h5>
<p class="wind-value">{{ weather.wind.speed }} mph</p>
</div>
</section>
</div>
</template>
<script>
import WeatherService from '../WeatherService';
export default {
name: 'Result',
data(){
return {
weather: [],
error: ''
}
},
async created() {
try {
this.weather = await WeatherService.getWeather();
} catch (error) {
this.error = error.message;
console.log(error);
}
}
}
</script>

You could pass some parameters like this
axios.get('/result', {
params: {
city: 'Portland'
}
})
This, of course, will need to be forwarded to your function to make it dynamic.
You can also use some headers or make a POST request rather than a GET. Not sure of the real differences between all those solutions tho.

Related

Csv data from Papa parse to React / useState to Node to MongoDB Atlas. insertMany

I implemented papa parse in React for the user to be able to upload the contents of a csv file into MongoDB (Atlas). Papa parse converts the Csv (with mulitple entries) into a json file which is then stored into a useState in React. Now I am trying to get this json data into MongoDB using Node/Express. It works flawlessly posting with Postman but not with React. So I guess it should be some mistake in the userFunctions.js or CSVReader.js file. Any help will be much appreciated!
// userFunctions.js
export const dataUpload = data => {
return axios.post('http://localhost:3002/event/create', {
seriennummer : data.seriennummer,
bezeichnung : data.bezeichnung,
verkaufspreis : data.verkaufspreis,
besonderheiten : data.besonderheiten,
})
.then(res => console.log('event created'))
.catch(err => console.log(err))
}
// CSVReader.js
const CSVReader = () => {
const [parsedCsvData, setParsedCsvData] = useState();
const parseFile = (file) => {
Papa.parse(file, {
header: true,
complete: (results) => {
setParsedCsvData(results.data);
},
});
};
console.log(parsedCsvData);
const onDrop = useCallback((acceptedFiles) => {
if (acceptedFiles.length) {
parseFile(acceptedFiles[0]);
}
}, []);
const {
getRootProps,
getInputProps,
isDragActive,
isDragAccept,
isDragReject,
} = useDropzone({
onDrop,
accept: "text/csv",
});
const createEvent = (e) => {
const newEvent = {
seriennummer : parsedCsvData,
bezeichnung : parsedCsvData,
verkaufspreis : parsedCsvData,
besonderheiten : parsedCsvData,
}
dataUpload(newEvent)
}
return (
<div>
<GlobalStyles />
<section
className="jumbotron breadcumb no-bg"
style={{ backgroundImage: `url(${"./img/background/subheader.jpg"})` }}
>
<div className="mainbreadcumb">
<div className="container">
<div className="row m-10-hor">
<div className="col-12">
<h1 className="text-center">CSV Datei hochladen - Uhren</h1>
</div>
</div>
</div>
</div>
</section>
<section className="container">
<div className="row">
<div className="col-lg-7 offset-lg-1 mb-5"></div>
<div
{...getRootProps({
className: `dropzone
${isDragAccept && "dropzoneAccept"}
${isDragReject && "dropzoneReject"}`,
})}
>
<input {...getInputProps()} />
{isDragActive ? (
<p>Drop the files here ...</p>
) : (
<h3>
<p>
Drag and Drop CSV File Here
</p>
</h3>
)}
</div>
<div>
<button type="submit" onClick={createEvent} class="form-control btn btnSign submit fs-3 ">CREATE NOW</button>
<div className="spacer-10"></div>
<div className="spacer-10"></div>
<table className="lead">
<thead>
<tr>
<th>Seriennummer</th>
<th>Firma</th>
<th>Preis</th>
<th>Besonderheiten</th>
</tr>
</thead>
<tbody>
{parsedCsvData &&
parsedCsvData.map((parsedData, index) => (
<tr key={index}>
<td>{parsedData.seriennummer}</td>
<td>{parsedData.bezeichnung}</td>
<td>{parsedData.verkaufspreis}</td>
<td>{parsedData.besonderheiten}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</section>
<Footer />
</div>
);
};
export default CSVReader;
// Controller
const createEvent = async (req, res) => {
try {
const event = await Event.insertMany(req.body)
res.json({
msg: "Created Event",
success: true,
data: event,
});
} catch (err) {
console.log(err);
res.json({
success: false,
data: err,
});
}
};
![console.log of the useState parsedCsvData][1]
[1]: https://i.stack.imgur.com/v5jZg.png
![Nodejs console][2]
[2]: https://i.stack.imgur.com/iPNXP.png
based on this error message, I believe req.body is stringified JSON. You need to do const data = JSON.parse(req.body) or use body-parser with express

Axios throwing Internal server error but api url works

I hope you are all safe.
My problem:
the URL is working fine, there is no undefined URL error there. when i entered good credentials, it works fine and take me to the location i wish. But anytime i am trying to view the errors, it doesn't appear. Even, in the if condition i try to console.log(res.data.errors) but nothing shows. Even console.log("Hello it not working") doesn't work at all in the if condition... I am confused. Would u help please? but the else works fine. what am i doing wrong please?
import React, { useState } from "react";
import { Link } from "react-router-dom";
import SideBar from "../components/SideBar";
import "./profil.css";
import axios from "axios";
function Profil() {
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleLogin = (e) => {
e.preventDefault();
const emailError = document.querySelector(".email.error");
const passwordError = document.querySelector(".password.error");
axios({
method: "post",
url: `${process.env.REACT_APP_API_URL}api/user/login`,
withCredentials: true,
data: {
email,
password,
},
})
.then((res) => {
if (res.data.errors) {
emailError.innerHTML = res.data.errors.email;
passwordError.innerHTML = res.data.errors.password;
} else {
window.location = "/";
}
})
.catch((err) => {
if (err.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(err.response.data);
console.log(err.response.status);
console.log(err.response.headers);
} else if (err.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(err.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', err.message);
}
console.log(err.config);
});
};
return (
<>
<SideBar />
<div className="form-container">
<input type="checkbox" id="flip" />
<div className="cover">
<div className="front">
<img src="dog-4977599_1920.jpg" alt="" />
<div className="text">
<span className="text-i">Welcome to ChablisLAB</span>
<span className="text-j">Please Login before continue</span>
</div>
</div>
<div className="back">
<img className="backImg" src="diary-92652_1920.jpg" alt="" />
<div className="text">
<span className="text-i">Welcome to ChablisLAB</span>
<span className="text-j">Just a few step to gain access</span>
</div>
</div>
</div>
<form>
<div className="form-content">
<div className="login_form">
<div className="title">Login</div>
<div className="input_boxes">
<div className="input_box">
<i className="bx bx-envelope"></i>
<input
type="email"
onChange={(e) => setEmail(e.target.value)}
value={email}
placeholder="Enter your email"
/>
</div>
<div className="email error"></div>
<div className="input_box">
<i className="bx bxs-lock"></i>
<input
type="password"
onChange={(e) => setPassword(e.target.value)}
value={password}
placeholder="Password"
/>
</div>
<div className="password error"></div>
<div className="box_forgot_pass">
<Link to="#">Forgot password?</Link>
</div>
<div className="button input_box">
<input onClick={handleLogin} type="submit" value="Login" />
</div>
<div className="text sign-up-text">
Don't have an account?
<label htmlFor="flip">Signup now</label>
</div>
</div>
</div>
</div>
</form>
</div>
</>
);
}
export default Profil;
.error{
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I think you need to console res.data.errors before you add if condition. There might be the chance you are putting conditions on the wrong properties which you are not getting in return as a response.
axios({
method: "post",
url: `${process.env.REACT_APP_API_URL}api/user/login`,
withCredentials: true,
data: {
email,
password,
},
})
.then((res) => {
console.log(res.data.errors, res.data); //check like this then put condition if you are getting res.data.errors property in response
if (res.data.errors) {
emailError.innerHTML = res.data.errors.email;
passwordError.innerHTML = res.data.errors.password;
} else {
window.location = "/";
}
})

react login register form sends empty data

I have a backend setup with node and express and frontend is React + Redux
The backend works well. I tested it all with insomina and i can successfully register a user and login.
On the front end side, everything looks ok except for the fact that when i try to login or register a user, it tells me that the input fields are required, which means that it sends an empty object to my backend. I also have a message in the console saying that componentWillReceiveProps(nextProps) is depricated and suggests using getDerivedStateFromProps instead. The issue is that i am new to React and have no idea how to convert that block. Can someone tell me? Is that even why the form sends an empty object?
EDIT: Added github repo for complete code
https://github.com/onidemon/wh-evcharge
Register.js is below, both login and Register have a componentWillReceiveProps block which i think might be causing the issue. Not sure how to convert them to getDerivedStateFromProps if that is even the cause of the problem.
import React, { Component } from "react";
import { Link, withRouter } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { registerUser } from "../../actions/authActions";
import classnames from "classnames";
class Register extends Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: "",
password2: "",
errors: {}
};
}
componentDidMount() {
// If logged in and user navigates to Register page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
const newUser = {
name: this.state.name,
email: this.state.email,
password: this.state.password,
password2: this.state.password2
};
this.props.registerUser(newUser, this.props.history);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div className="row">
<div className="col s8 offset-s2">
<Link to="/" className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to
home
</Link>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Register</b> below
</h4>
<p className="grey-text text-darken-1">
Already have an account? <Link to="/login">Log in</Link>
</p>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.name}
error={errors.name}
id="name"
type="text"
className={classnames("", {
invalid: errors.name
})}
/>
<label htmlFor="name">Name</label>
<span className="red-text">{errors.name}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">{errors.email}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">{errors.password}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password2}
error={errors.password2}
id="password2"
type="password"
className={classnames("", {
invalid: errors.password2
})}
/>
<label htmlFor="password2">Confirm Password</label>
<span className="red-text">{errors.password2}</span>
</div>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Sign up
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Register.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ registerUser }
)(withRouter(Register));
Login.js is below
import React, { Component } from "react";
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { loginUser } from "../../actions/authActions";
import classnames from "classnames";
class Login extends Component {
constructor() {
super();
this.state = {
email: "",
password: "",
errors: {}
};
}
componentDidMount() {
// If logged in and user navigates to Login page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
const userData = {
email: this.state.email,
password: this.state.password
};
this.props.loginUser(userData);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div style={{ marginTop: "4rem" }} className="row">
<div className="col s8 offset-s2">
<Link to="/" className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to
home
</Link>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Login</b> below
</h4>
<p className="grey-text text-darken-1">
Don't have an account? <Link to="/register">Register</Link>
</p>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email || errors.emailnotfound
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">
{errors.email}
{errors.emailnotfound}
</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password || errors.passwordincorrect
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">
{errors.password}
{errors.passwordincorrect}
</span>
</div>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Login
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Login.propTypes = {
loginUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ loginUser }
)(Login);
EDIT: Added AuthActions.js
import axios from "axios";
import setAuthToken from "../utils/setAuthToken";
import jwt_decode from "jwt-decode";
import { GET_ERRORS, SET_CURRENT_USER, USER_LOADING } from "./types";
// Register User
export const registerUser = (userData, history) => dispatch => {
axios
.post("/api/users/register", userData)
.then(res => history.push("/login"))
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
// Login - get user token
export const loginUser = userData => dispatch => {
axios
.post("/api/users/login", userData)
.then(res => {
// Save to localStorage
// Set token to localStorage
const { token } = res.data;
localStorage.setItem("jwtToken", token);
// Set token to Auth header
setAuthToken(token);
// Decode token to get user data
const decoded = jwt_decode(token);
// Set current user
dispatch(setCurrentUser(decoded));
})
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
// Set logged in user
export const setCurrentUser = decoded => {
return {
type: SET_CURRENT_USER,
payload: decoded
};
};
// User loading
export const setUserLoading = () => {
return {
type: USER_LOADING
};
};
// Log user out
export const logoutUser = () => dispatch => {
// Remove token from local storage
localStorage.removeItem("jwtToken");
// Remove auth header for future requests
setAuthToken(false);
// Set current user to empty object {} which will set isAuthenticated to false
dispatch(setCurrentUser({}));
};
I looked on your github project.
If I am not mistaken I haven't seen you using in your server the bodyparser.json() function. You only use the bodyParser.urlencoded(), which convert url parameters into processable objects.
Add as well bodyParser.json(), then you would get the incoming data from the body of the request as well. Then you should have it I believe.

Why is my delete function resulting in an undefined value error?

I'm building app using ReactJs and NodeJs. App is displaying data from database or all rooms. Room have to be abled to be created, edited and deleted.
Create and edit is working. The delete function is not.
Here is code:
Rooms.js
export default class RoomsAdmin extends React.Component {
constructor(props) {
super(props);
this.state = { rooms: [] };
this.delete = this.delete.bind(this);
}
componentDidMount() {
axios.get('http://localhost:3090/admin/')
.then(response => {
this.setState({ rooms: response.data });
})
.catch(function (error){
console.log(error);
})
}
componentDidUpdate() {
axios.get('http://localhost:3090/admin/')
.then(response => {
this.setState({ rooms: response.data });
})
.catch(function (error){
console.log(error);
})
}
delete() {
axios.get('http://localhost:3090/admin/delete/'+this.props.room._id)
.then(console.log('Deleted'))
.catch(err => console.log(err))
}
roomList() {
const Room = props => (
<div className="col-md-4">
<div className="card mb-4 shadow-sm">
<div className="card-body">
<h5 class="card-title">{props.room.title}</h5>
<p className="card-text">{props.room.description}</p>
<div className="d-flex justify-content-between align-items-center">
<div className="btn-group">
<Link className="btn btn-sm btn-outline-secondary"
to={ "/edit/"+props.room._id}>Edit</Link>
<button onClick={this.delete}>Delete</button>
</div>
</div>
</div>
</div>
</div>
)
return this.state.rooms.map(function (currentRoom, i) {
return <Room room={currentRoom} key={i} />
});
}
render() {
return (
<div>
<Header />
<div>
<div className="album py-5 bg-light">
<div className="container">
<div className="row">
{this.roomList()}
</div>
</div>
</div>
</div>
</div>
)
}
}
After clicking on delete I get this error:
Uncaught TypeError: Cannot read property '_id' of undefined
Any tip would be highly appreciated.
You are confusing a parent -> child relationship here. There is only one component, so you don't have props.room. Instead just pass the room id to be deleted in the callback function.
<button onClick={this.delete.bind(null, props.room._id}>Delete</button>
and your handler function
delete(id) {
I would rename your handler to be a little more explicit, also delete is a keyword in javascript so probably best to avoid that function name.
deleteRoom(id) {
axios.get(`http://localhost:3090/admin/delete/${id}`)
.then(console.log('Deleted'))
.catch(err => console.log(err))
Edit, I cleaned up the code a little, moved the child component outside of the parent so you dont need to reinitialize that component each time you render.
export default class RoomsAdmin extends React.Component {
constructor(props) {
super(props)
this.state = { rooms: [] }
this.deleteRoom = this.deleteRoom.bind(this)
}
componentDidMount() {
axios.get('http://localhost:3090/admin/')
.then(response => {
this.setState({ rooms: response.data })
})
.catch((error) => {
console.log(error)
})
}
componentDidUpdate() {
axios.get('http://localhost:3090/admin/')
.then(response => {
this.setState({ rooms: response.data })
})
.catch((error) => {
console.log(error)
})
}
deleteRoom(id) {
axios.get(`http://localhost:3090/admin/delete/${id}`)
.then(console.log('Deleted'))
.catch(err => console.log(err))
}
roomList() {
return this.state.rooms.map((currentRoom, i) => (
<Room
room={currentRoom}
onDelete={this.deleteRoom.bind(null, currentRoom._id)}
key={i}
/>
))
}
render() {
return (
<div>
<Header />
<div>
<div className="album py-5 bg-light">
<div className="container">
<div className="row">{this.roomList()}</div>
</div>
</div>
</div>
</div>
)
}
}
const Room = props => (
<div className="col-md-4">
<div className="card mb-4 shadow-sm">
<div className="card-body">
<h5 class="card-title">{props.room.title}</h5>
<p className="card-text">{props.room.description}</p>
<div className="d-flex justify-content-between align-items-center">
<div className="btn-group">
<Link
className="btn btn-sm btn-outline-secondary"
to={`/edit/${props.room._id}`}
>
Edit
</Link>
<button onClick={props.onDelete}>Delete</button>
</div>
</div>
</div>
</div>
</div>
)

Reactjs - setState doesn't re-render after update

Simply all i'm trying to do is re render the notes list when i add another note to the database. i tried several methods even redux dispatch method. but none worked and it kinda make sense because when i add a note i don't add anything so it can get the updated notes through /budget. maybe i have a big misunderstanding.
here's how i add a new note
export function saveOneNote() {
// saving a note
const _id = $('input[name="_id"]').val(),
firstItem = $('input[name="firstItem"]').val(),
firstPrice = $('input[name="firstPrice"]').val(),
secondItem = $('input[name="secondItem"]').val(),
secondPrice = $('input[name="secondPrice"]').val(),
thirdItem = $('input[name="thirdItem"]').val(),
thirdPrice = $('input[name="thirdPrice"]').val(),
tBudget = $('input[name="tBudget"]').val();
let currency = $("#currency").val();
console.log(currency);
$.ajax({
url: "/newNote",
type: "post",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({
currency,
_id,
firstItem,
firstPrice,
secondItem,
secondPrice,
thirdItem,
thirdPrice,
tBudget
}),
success: function(Data) {
console.log("note was saved!", Data);
},
error: function(err, status, xhr) {
console.log("err", err);
}
});
}
here's how i fetch notes
class ShowAll extends Component {
constructor(props){
super(props);
this.state = {
Data: [],
length:[],
searchbyid:[],
isLoggedIn:[]
}
}
componentDidMount(){
// fetch notes
Rquest.get('/budget').then((res)=>{
let DataString = Array.from(res.body);
this.setState((prevState,props)=>{
return {
Data: DataString,
length: res.body.length
}
})
}).catch((err)=> {
console.log(err);
})
// check if user is logged in
Request.get('/auth').then((user)=>{
if(user){
this.setState({
isLoggedIn: true
})
}
}).catch((err)=> {
this.setState({
isLoggedIn: false
})
});
}
render(){
const count = this.state.length;
const myNotes = this.state.Data;
const isLoggedIn = this.state.isLoggedIn;
const listItems = myNotes.map((dynamicData)=>{
return(
<Fragment key={dynamicData.id}>
<div className='jumbotron'>
<div className='row'>
<button className='btn btn-danger delete-note-btn' onClick={DeleteOneNote}>Delete</button>
<input className='col-12 title form-control' id='deleteById' value={dynamicData._id} readOnly/>
<div className="dropdown-divider"></div> {/*line divider*/}
<div className='col-6' >
<ul className='list-unstyled'>
<li className='items'>items</li>
<li >{dynamicData.firstItem}</li>
<li >{dynamicData.secondItem}</li>
<li >{dynamicData.thirdItem}</li>
{/* <li>Total Budget :</li> */}
</ul>
</div>
<div className='dynamicData col-6'>
<ul className ='list-unstyled'>
<li className='prices'>Prices</li>
<li>{dynamicData.firstPrice} {dynamicData.currency}</li>
<li>{dynamicData.secondPrice} {dynamicData.currency}</li>
<li>{dynamicData.thirdPrice} {dynamicData.currency}</li>
</ul>
</div>
</div>
<h3 className='col-12 totalprice'>{dynamicData.tBudget} {dynamicData.currency}</h3>
</div>
</Fragment>
)
})
return (
<Fragment>
{isLoggedIn ===true?(
<div className='myNotesList '>
number of notes : {count}
{listItems}
</div>
):(
<Fragment>
</Fragment>
)
}
</Fragment>
)
}
}
React components are re-rendering only on state or props change. In your code - you're not mutating state nor props of your component.
What you should do in your case probably is to re-fetch the items after save or add the new items to the state or pass through props.
Example:
class Notes extends React.Component {
state = { note: '', notes: [] }
changeNote = ({ target: { value } }) => {
this.setState({ note: value });
}
addNote = () => {
this.setState((state) => ({ notes: [...state.notes, state.note] }));
}
render() {
return (
<div>
<input type="text" onChange={this.changeNote} />
<button onClick={this.addNote}>Add</button>
<ul>
{this.state.notes.map(note =>
<li>{note}</li>
)}
</ul>
</div>
)
}
}
ReactDOM.render(
<Notes />,
document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js"></script>
<div id="app">
</div>

Resources