Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialKilleon Patterson
18,528 PointsRendering a change in data (MERN App)
I'm working on a project that creates a basic MERN application. The interface allows a client to enter a message into an input field, press a button, and then display that message to the client along with a newly created id.
// client/src/App.js;
import React, { Component } from "react";
import axios from 'axios';
import './App.css';
class App extends Component {
// initialize our state
state = {
data: [],
id: 0,
message: null,
intervalIsSet: false,
idToDelete: null,
idToUpdate: null,
objectToUpdate: null
};
// when component mounts, first thing it does is fetch all existing data in our db
// then we incorporate a polling logic so that we can easily see if our db has
// changed and implement those changes into our UI
componentDidMount() {
this.getDataFromDb();
if (!this.state.intervalIsSet) {
let interval = setInterval(this.getDataFromDb, 1000);
this.setState({ intervalIsSet: interval});
}
}
// never let a process live forever
// always kill a process everytime we are done using it
componentWillUnmount() {
if (this.state.intervalIsSet) {
clearInterval(this.state.intervalIsSet);
this.setState({ intervalIsSet: null });
}
}
// just a note, here, in the front end, we use the id key of our data object
// in order to identify which we want to Update or delete.
// for our back end, we use the object id assigned by MongoDB to modify
// data base entries
// our first get method that uses our backend api to
// fetch data from our data base
getDataFromDb = () => {
fetch("http://localhost:3001/api/getData")
.then(data => data.json())
.then(res => this.setState({ data: res.data}));
};
//our put method that uses our backend api
//to create new query into our data base
putDataToDB = message => {
let currentIds = this.state.data.map(data => data.id);
let idToBeAdded = 0;
while (currentIds.includes(idToBeAdded)) {
++idToBeAdded;
}
axios.post("http://localhost:3001/api/putData", {
id: idToBeAdded,
message: message
});
};
// our delete method that uses our backend api
// to remove existing database information
deleteFromDB = idTodelete => {
let objIdToDelete = null;
this.state.data.forEach(dat => {
if (dat.id === idTodelete) {
objIdToDelete = dat._id;
}
});
axios.delete("http://localhost:3001/api/deleteData", {
data: {
id: objIdToDelete
}
});
};
// our update method that uses our backend api
// to overwrite existing data base information
updateDB = (idToUpdate, updateToApply) => {
let objIdToUpdate = null;
this.state.data.forEach(dat => {
if (dat.id === idToUpdate) {
objIdToUpdate = dat._id;
}
});
axios.post("http://localhost:3001/api/updateData", {
id: objIdToUpdate,
update: { message: updateToApply }
});
};
// here is our UI
// it is easy to understand their functions when you
// see them render into our screen
render() {
const { data } = this.state;
return (
<div>
<ul>
{data.length <= 0
? "NO DB ENTRIES YET"
: data.map(dat => (
<li style={{ padding: "10px" }} key={data.message}>
<span style={{ color: "gray" }}> id: </span> {dat.id} <br/>
<span style={{ color: "gray" }}> data: </span>
{dat.message}
</li>
))}
</ul>
<div style={{ padding: "10px" }}>
<input
type="text"
onChange={e => this.setState({ message: e.target.value })}
placeholder="add something in the database"
style={{ width: "200px" }}
/>
<button onClick={() => this.putDataToDB(this.state.message)}>
ADD
</button>
</div>
<div style={{ padding: "10px" }}>
<input
type="text"
style={{ width: "200px" }}
onChange={e => this.setState({ idToDelete: e.target.value })}
placeholder="put id of item to delete here"
/>
<button onClick={() => this.deleteFromDB(this.state.idToDelete)}>
DELETE
</button>
</div>
<div style={{ padding: "10px" }}>
<input
type="text"
style={{ width: "200px" }}
onChange={e => this.setState({ idToUpdate: e.target.value })}
placeholder="id of item to update here"
/>
<input
type="text"
style={{ width: "200px" }}
onChange={e => this.setState({ updateToApply: e.target.value })}
placeholder="put new value of the item here"
/>
<button
onClick={() =>
this.updateDB(this.state.idToUpdate, this.state.updateToApply)
}
>
UPDATE
</button>
</div>
</div>
);
}
}
export default App;
The buttons are successfully posting to MongoDB:Atlas and can be deleted from the cloud. Although, the app begins with a display to the client "NO DB ENTRIES YET". After the client enters information that display is supposed to show the message, along with an id.
And it doesn't. I'd appreciate some insight if you have any.
``react``
<ul>
{data.length <= 0
? "NO DB ENTRIES YET"
: data.map(dat => (
<li style={{ padding: "10px" }} key={data.message}>
<span style={{ color: "gray" }}> id: </span> {dat.id} <br/>
<span style={{ color: "gray" }}> data: </span>
{dat.message}
</li>
))}
</ul>
2 Answers
Juan Lopez
Treehouse Project ReviewergetDataFromDb = () => {
fetch("http://local:3001/api/getData")
.then(data => data.json())
.then(res => this.setState({ data: res.data}));
};
Double Check the url where you are fetching but I think you might have a typo and it should be localhost:3001
and since the fetching is failing the data array in your state never gets updated and thus your conditional rendering is always showing "NO DB ENTRIES YET"
Tariku Kebede
9,706 Pointsi think the problem is here: const { data } = this.state; i think this distructured object should not be constant.
Killeon Patterson
18,528 PointsKilleon Patterson
18,528 PointsHello Juan,
Thank you for your reply. There was a typo with the fetch method. I made the edit to "local:3001" to "localhost:3001." Although, now it's making endless calls to resource, not giving the chance to modify anything, and causing 304 responses in the console.
My intended logic for the loop appears to have the correct syntax?