Data Fetching with React using useEffect - reactjs

What I am trying to do is when the user click the edit button, this will send him to a new page where he can modify the info he already entered. The problem I am facing is that the new page is not showing the data previously entered, so that the user can make his changes. Also, the submit button to send those changes is not working. These are the errors I am getting: src\components\RestaurantList.jsx
Line 25:8: React Hook useEffect has a missing dependency: 'setRestaurants'. Either include it or remove the dependency array react-hooks/exhaustive-deps
Line 31:19: 'response' is assigned a value but never used no-unused-vars
src\components\UpdateRestaurant.jsx
Line 9:12: 'restaurants' is assigned a value but never used no-unused-vars
Line 38:8: React Hook useEffect has a missing dependency: 'code'. Either include it or remove the dependency array react-hooks/exhaustive-deps
My code for the component I am working on:
import React, {useState, useContext, useEffect} from 'react';
import { useHistory, useParams } from 'react-router-dom';
import RestaurantFinder from '../apis/RestaurantFinder';
import { RestaurantsContext } from '../context/RestaurantsContext';
const UpdateRestaurant = (props) => {
const {code} = useParams();
const {restaurants} = useContext(RestaurantsContext);
let history = useHistory();
const [name, setName] = useState("");
const [value, setValue] = useState ("");
const [strain, setStrain] = useState ("");
const [weight, setWeight] = useState ("");
const [authors, setAuthors] = useState ("");
const [number, setNumber] = useState ("");
const [page, setPage] = useState ("");
const [date, setDate] = useState ("");
useEffect(() => {
const fetchData = async () => {
const response = await RestaurantFinder.get(`/${code}`);
console.log(response.data.data);
setName(response.data.data.restaurant.name);
setValue(response.data.data.restaurant.value);
setStrain(response.data.data.restaurant.strain);
setWeight(response.data.data.restaurant.weight);
setAuthors(response.data.data.restaurant.authors);
setNumber(response.data.data.restaurant.number);
setPage(response.data.data.restaurant.page);
setDate(response.data.data.restaurant.date);
};
fetchData();
}, []);
const handleSubmit = async(e) => {
e.preventDefault();
const updatedRestaurant = await RestaurantFinder.put(`/${code}`, {
name,
value,
strain,
weight,
authors,
number,
page,
date,
});
console.log(updatedRestaurant);
history.push("/");
};
return (
<div>
<form action="">
<div className="form-group">
<label htmlFor="name">Name</label>
<input value={name} onChange={(e) => setName(e.target.value)} code="name" className="form-control" type="text" />
</div>
<div className="form-group">
<label htmlFor="Value">Value</label>
<input value={value} onChange={(e) => setValue(e.target.value)} code="value" className="form-control" type="float" />
</div>
<div className="form-group">
<label htmlFor="Strain">Strain</label>
<input value={strain} onChange={(e) => setStrain(e.target.value)} code="strain" className="form-control" type="text" />
</div>
<div className="form-group">
<label htmlFor="Weight">Weight</label>
<input value={weight} onChange={(e) => setWeight(e.target.value)} code="weight" className="form-control" type="float" />
</div>
<div className="form-group">
<label htmlFor="Author">Author</label>
<input value={authors} onChange={(e) => setAuthors(e.target.value)} code="authors" className="form-control" type="text" />
</div>
<div className="form-group">
<label htmlFor="Number">Number</label>
<input value={number} onChange={(e) => setNumber(e.target.value)} code="number" className="form-control" type="number" />
</div>
<div className="form-group">
<label htmlFor="Page">Page</label>
<input value={page} onChange={(e) => setPage(e.target.value)} code="page" className="form-control" type="number" />
</div>
<div className="form-group">
<label htmlFor="date">Date</label>
<input value={date} onChange={(e) => setDate(e.target.value)} code="date" className="form-control" type="number" />
</div>
<button onClick={handleSubmit} type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
)
}
export default UpdateRestaurant

for reusable code, it may be best to just do something like this.
This is probably not the answer, but I hope it helps you find out the answer.
const [data, setData ] = useState({restraunt.loaded:"false"});
useEffect(() => {
const fetch = async () => {
const response = await RestaurantFinder.get(`/${code}`);
console.log(response.data.data);
setData({...response.data.data, restraunt.loaded:"true"});
};
fetch();
},[Data.restraunt.loaded])
const {name, value , page, loaded } = Data.restaurant;
return (
<div><h1>{loaded}</h1>
</div>
)
If it shows loaded as false then you know it is because of the data not loading.

Related

React form not rendering with selectedRow data

I am new to React.js so forgive me if this is an obvious mistake. I have a list of data with an update button on each row and it is supposed to open a form with the relevant fields already populated with the selectedRow.data but the controls are blank. The URL in Postman is giving the right response so that's not the problem. Any help would be appreciated.
Also getting this error in my console:
"Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component"
Here is my code:
import React, { useState, useContext, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { AppContext } from '../context/AppContext';
import AdminPortal from '../apis/AdminPortal'
const OrganizationUpdateForm = (props) => {
const {id} = useParams()
const { organizations } = useContext(AppContext);
const [name, setName] = useState("");
const [shortName, setShortName] = useState("");
const [parentOrg, setParentOrg] = useState("");
const [website, setWebsite] = useState("");
const [comments, setComments] = useState("");
useEffect(() => {
async function fetchData () {
const response = await AdminPortal.get(`organizations/${id}`);
console.log(response.data.data);
setName(response.data.data.organizations.name);
setShortName(response.data.data.organizations.short_name);
setParentOrg(response.data.data.organizations.parent_org);
setWebsite(response.data.data.organizations.website);
setComments(response.data.data.organizations.comments);
};
fetchData();
}, []);
let Navigate = useNavigate();
const handleSubmit = async (e) => {
e.preventDefault();
const updateOrganization = await AdminPortal.put(`organizations/${id}`, {
name,
short_name: shortName,
parent_org: parentOrg,
website,
comments
});
Navigate("/");
};
return (
<div>
<form action=''>
<div className="form-group">
<label htmlFor='name'>Name</label>
<input
value={name}
onChange={(e) => setName(e.target.value)}
id="name"
className="form-control"
type="text"
/>
</div>
<div className="form-group">
<label htmlFor='short_name'>Short Name</label>
<input
value={shortName}
onChange={(e) => setShortName(e.target.value)}
id="name"
className="form-control"
type="text"
/>
</div>
<div className="form-group">
<label htmlFor='parent_org'>Parent Organization</label>
<input
value={parentOrg}
onChange={(e) => setParentOrg(e.target.value)}
id="name"
className="form-control"
type="text"
/>
</div>
<div className="form-group">
<label htmlFor='website'>Website</label>
<input
value={website}
onChange={(e) => setWebsite(e.target.value)}
id="name"
className="form-control"
type="text"
/>
</div>
<div className="form-group">
<label htmlFor='comments'>Comments</label>
<input
value={comments}
onChange={(e) => setComments(e.target.value)}
id="name"
className="form-control"
type="text"
/>
</div>
{/* <button
type="submit"
onClick={handleSubmit}
className="btn btn-primary"
>
Submit
</button> */}
</form>
</div>
)
}
export default OrganizationUpdateForm
{
"status": "success",
"results": 1,
"data": {
"organizations": [
{
"id": 20,
"name": "International Aids Vaccine Initiative",
"name_localized": "IAVI",
"parent_org_id": null,
"website": "",
"comment": "",
"create_date": "2019-08-26T12:42:49.457Z",
"logo": null,
"short_name": "IAVI"
}
]
}
}
Above is the response when I hit the API with "http://localhost:3000/api/v1/organizations/20" which is the correct response. Below is the code for AdminPortal
import axios from "axios";
export default axios.create({
baseURL: "http://localhost:3000/api/v1/"
})
This is a screen capture of the network response
The last line in the {id} has no response and I'm wondering if that might be a clue and I'm also surprise to see the port change from 3001 to 3000. I did change to response.data.organizations which seems to match with the structure in the response but that didn't make a difference. Here is what I changed:
useEffect(() => {
async function fetchData () {
// const response = await AdminPortal.get(`organizations/${id}`);
const response = await AdminPortal.get(`organizations/${id}`);
console.log(response.dataorganizations);
setName(response.data.organizations.name);
setShortName(response.data.organizations.short_name);
setParentOrg(response.data.organizations.parent_org);
setWebsite(response.data.organizations.website);
setComments(response.data.organizations.comments);
};
fetchData();
}, []);
Thanks for your support.

Can't type in textarea when displayed

import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState("")
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
console.log(name)
}
return (
<form onSubmit={handleSumbit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={handleSumbit}></textarea>
<input type="submit" />
</form>
)
}
When the text box is displayed I cannot type in it.
What am I doing wrong...?
import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState('')
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
console.log(name)
}
return (
<form onSubmit={handleSumbit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={(e) => setTextArea(e.target.value)}></textarea>
<input type="submit" />
</form>
)
}
The textarea is a controlled input - if you are going to tie the value of the <textarea> to the textArea state variable, you need to update that state variable whenever the user changes the input.
Shouldn't the onChange={handleSumbit} of the textarea be
onChange={(e) => setTextArea(e.target.value)}
import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState("")
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
console.log(name)
}
return (
<form onSubmit={handleSumbit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setTextArea(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={handleSumbit}></textarea>
<input type="submit" />
</form>
)
}
Firstly
You implicitly set the value of your text area using the textArea variable which has an initial state of "" (an empty string).
React automatically refreshes the real DOM from the virtual DOM after every change in state. But the value of your textArea variable doesn't change with this event, so you have to update the state when a value is entered like this:
onChange={(e) => setTextArea(e.target.value)}
After reading your code, I guessed what you wanted to achieve is to prevent the submit button from submitting the form by default and instead logs the name on the console.
I believe this is the code you wanted to achieve:
import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState('')
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
console.log(name)
}
return (
<form onSubmit={handleSumbit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={(e) => setTextArea(e.target.value)}></textarea>
<input type="submit" />
</form>
)
You can't type here the event not written by you properly, so, you state textarea not updated yet. just needed to change one as a similar name textbox. just replace
<textarea value={textArea} onChange={handleSumbit}></textarea>
to
<textarea value={textArea} onChange={(e) => setTextArea(e.target.value)}></textarea>
Full code here edited,
import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState('')
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
// console here form data
}
return (
<form onSubmit={(e)=>handleSumbit(e)}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={(e) => setTextArea(e.target.value)}></textarea>
<input type="submit" value="Submit now!" />
</form>
)
I Hope, work fine using this code
Thanks

put method not working with react axios api method

I have this api running on my localhost, using drf. I defined a put method to use to update an object. When i do this in the backend it works, everything gets updated, but when i do it in the frontend nothing gets updated but i get a 200 OK status code. How can i make it work?
Here is my react code:
import React, { useState, useEffect } from 'react';
import { useHistory, useParams } from 'react-router';
import axios from 'axios';
const EkoEditPage = () => {
const [disco, setDisco] = useState("")
const [feederSource33kv, setFeederSource33kv] = useState("")
const [injectionSubstation, setInjectioSubstation] = useState("")
const [feederName, setFeederName] = useState("")
const [band, setBand ] = useState("")
const [status, setStatus] = useState("")
const history = useHistory();
const { id } = useParams();
const loadEkoMyto = async () => {
const { data } = await axios.get(`http://127.0.0.1:8000/main/view/${id}`);
setDisco(data.dicso)
setFeederSource33kv(data.feeder_source_33kv)
setInjectioSubstation(data.injection_substation)
setFeederName(data.feeder_name )
setBand(data.band)
setStatus(data.status)
}
const updateEkoMyto = async () => {
let formField = new FormData()
formField.append('disco', disco)
formField.append('feeder_source_33kv', feederSource33kv)
formField.append('injecttion_substation', injectionSubstation)
formField.append('feeder_name',feederName)
formField.append('band', band)
formField.append('status', status)
await axios({
method: 'PUT',
url: `http://127.0.0.1:8000/main/edit/${id}`,
data: formField
}).then(response => {
console.log(response.data)
})
}
useEffect (() => {
loadEkoMyto()
}, [])
return (
<div className="container">
<div className="w-75 mx-auto shadow p-5">
<h2 className="text-center mb-4">Update A Student</h2>
<div className="form-group">
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
name="disco"
value={disco}
onChange={(e) => setDisco(e.target.value)}
/>
</div>
<div className="form-group">
<input
className="form-control form-control-lg"
placeholder="Enter Your E-mail Address"
name="feeder_source_33kv"
value={feederSource33kv}
onChange={(e) => setFeederSource33kv(e.target.value)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="Enter Your Phone Number"
name="injection_substation"
value={injectionSubstation}
onChange={(e) => setInjectioSubstation(e.target.value)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
placeholder="Enter Your address Name"
name="address"
value={feederName}
onChange={(e) => setFeederName(e.target.value)}
/>
</div>
<div className="form-group">
<input
type="text"
className="form-control form-control-lg"
name="address"
value={band}
onChange={(e) => setBand(e.target.value)}
/>
</div>
<select name="status" onChange={(e) => setStatus(e.target.value)}>
<option value={status}>Yes</option>
<option value={status}>No</option>
</select>
<button className="btn btn-primary btn-block" onClick={updateEkoMyto}>Update Eko</button>
</div>
</div>
);
};
export default EkoEditPage;
}

How can I get radio button value and upload it into firebase?

In this code, I want to upload the radio button value and store it in firebase database.I want use the simplest way to solve that. I see other code will use constructor but I do not know whether I can use simpler way to solve it. how can I do that ?
import React, { useState } from "react";
import ReactPlayer from "react-player";
import Array from "../Array";
import firebase from "firebase";
export default () => {
const [selected, setSelected] = useState("");
return (
<div>
<div className="video">
<ReactPlayer url={Array[0]} playing />
</div>
<label>Guess whether this video is fake or real ?</label> <br />
<label>
<input
type="radio"
name="answer"
value="real"
onChange={e => setSelected(e.target.value)}
/>
real
</label>
<label>
<input
type="radio"
name="answer"
value="fake"
onChange={e => setSelected(e.target.value)}
/>
fake
</label>
</div>
);
};
I would do it like this:
import React from "react";
....
export default () => {
const [state, setState] = React.useState({});
const handleInputChange = e => {
const { name, value } = e.target;
console.log(name, value);
setState(state => {
const newState = { ...state, [name]: value }
//post newState to firebase
return newState
});
};
return (
<div>
<div className="video">
<ReactPlayer url={Array[0]} playing />
</div>
<div>{JSON.stringify(state)}</div>
<label>Guess whether this video is fake or real ?</label> <br />
<label>
<input
type="radio"
name="answer1"
value="real"
onChange={handleInputChange}
/>
real
</label>
<label>
<input
type="radio"
name="answer2"
value="fake"
onChange={handleInputChange}
/>
fake
</label>
</div>
);
};

Trouble with bootstrap-validate and useState (React)

I'm using bootstrap-validate for my forms, and I'm running into a really weird problem. If I try to use setIsValidEmail in the callback then whenever I type [some-text]#[some-text].com . I can't type anything pass the 'c' in 'com'. It works fine if I leave the callback and just remove setIsValidEmail.
Repo: https://github.com/mlelien/testtest
import React, { useState } from 'react'
import * as bootstrapValidate from 'bootstrap-validate'
window.bootstrapValidate = bootstrapValidate
const SignUp2 = () => {
const [email, setEmail] = useState('')
const [isValidEmail, setIsValidEmail] = useState(false)
const onEmailChange = (e) => {
const newEmail = e.target.value
setEmail(newEmail)
bootstrapValidate('#form-email', 'email:Invalid email', (isValid) => {
setIsValidEmail(isValid)
})
}
return (
<div className="container">
<h3>SIGN UP</h3>
<form>
<div className="form-group">
<label htmlFor="form-email">
Email address
<input
type="email"
className="form-control"
id='form-email'
aria-describedby='enter email'
placeholder='Enter email'
value={email}
onChange={onEmailChange}
/>
</label>
</div>
</form>
</div>
)
}
export default SignUp2

Resources