0

I am new in ReactJS. I am creating simple CRUD operation with the help of PHP API. Insert, delete and update is working good. But when I click on edit button, related data is not showing in fields.

App.js is:

import React from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Insert from './components/Insert';
import View from './components/View';
import Edit from './components/Edit';

function App() {
return (
<Router>
  <div className="container">
  <nav>
    <div>
      <h4>React CRUD</h4>
      <div>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/insert">Insert</Link>
        </li>
        <li>
          <Link to="/view">View</Link>
        </li>
      </ul>
      </div>
    </div>
    </nav>

    <Switch>
      <Route exact path="/insert" component={Insert} />
      <Route path="/edit/:id" component={Edit} />
      <Route path="/view" component={View} />
    </Switch>
  </div>
</Router>
);
}
export default App;

View.js is:

import React from 'react';
import axios from 'axios';
import RecordList from './RecordList';

export default class View extends React.Component{
constructor(props){
super(props);
this.state = {
  userslist: []
};
}
componentDidMount(){
axios.get('http://localhost/react_crud2_api/view.php')
.then(response => {
  this.setState({
    userslist: response.data
  });
})
.catch(function(error){
  console.log(error);
})
}
usersList(){
return this.state.userslist.map(function(val,key){
  return <RecordList obj={val} key={key} />
});
}
render(){
return(
  <div>
    <h3>Users List</h3>
    <table>
    <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Email</th>
      <th colSpan="2">Action</th>
    </tr>
    </thead>
    <tbody>{this.usersList()}</tbody>
    </table>
  </div>
 )
}

}

RecordList is:

import React from 'react';
import axios from 'axios';
import { Redirect } from 'react-router';
import { Link } from 'react-router-dom';
export default class RecordList extends React.Component{
constructor(props){
super(props);
this.deletesss = this.deletesss.bind(this);
this.state = {
  redirect: false
}
}

deletesss(){
axios.get('http://localhost/react_crud2_api/delete.php?id='+this.props.obj.id)
.then(this.setState({redirect: true}))
.catch(err => console.log(err))
}
render(){
const { redirect } = this.state;
if (redirect) {
  return <Redirect to='/view' />;
}
return(
  <tr>
    <td>{this.props.obj.first_name}</td>
    <td>{this.props.obj.last_name}</td>
    <td>{this.props.obj.email}</td>
    <td><Link to={'/edit/'+this.props.obj.id}>Edit</Link></td>
    <td><button onClick={this.deletesss}>Delete</button></td>
  </tr>

)
}
}

Edit.js:

import React from 'react';
import axios from 'axios';
import { Redirect } from 'react-router';

export default class Edit extends React.Component{

constructor(props){
super(props);
this.state = {
  first_name: '',
  last_name: '',
  email: '',
  redirect: false
}
this.onChangeFirstName = this.onChangeFirstName.bind(this);
this.onChangeLastName = this.onChangeLastName.bind(this);
this.onChangeEmail = this.onChangeEmail.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}

componentDidMount(){
axios.get('http://localhost/react_crud2_api/edit.php?id='+this.props.match.params.id)
.then(response => {
  this.setState({
    first_name: response.data.first_name,
    last_name: response.data.last_name,
    email: response.data.email
  });
})
.catch(function(error){
  console.log(error);
})
}

onChangeFirstName(e){
this.setState({
  first_name: e.target.value
})
}
onChangeLastName(e){
this.setState({
  last_name: e.target.value
})
}
onChangeEmail(e){
this.setState({
  email: e.target.value
})
}
onSubmit(e){
e.preventDefault();
const obj = {
  first_name: this.state.first_name,
  last_name: this.state.last_name,
  email: this.state.email
};
//console.log(obj)
axios.post('http://localhost/react_crud2_api/update.php?id='+this.props.match.params.id, obj)
.then(this.setState({redirect: true}));
//this.props.history.push('/view');
}

render(){
// const { redirect } = this.state;
// if (redirect) {
//   return <Redirect to='/view' />;
// }
return(
  <div style={{ marginTop: 10 }}>
  <h3>Add New User</h3>
  <form onSubmit={this.onSubmit}>
    <div>
      <label>First Name</label>
      <input type="text" defaultValue={this.state.first_name} onChange={this.onChangeFirstName}  />
    </div>
    <div>
      <label>Last Name</label>
      <input type="text" defaultValue={this.state.last_name} onChange={this.onChangeLastName} />
    </div>
    <div>
      <label>Email</label>
      <input type="text" defaultValue={this.state.email} onChange={this.onChangeEmail} />
    </div>
    <div>
      <input type="submit" value="Update User" />
    </div>

  </form>
  </div>
)
}
}

After click on edit button. Blank form is showing, but when I fill some data then it updates data. Why data is not showing at edit page.

Vinod
  • 123
  • 1
  • 3
  • 14

2 Answers2

1
import React from 'react';
import axios from 'axios';
import { Redirect } from 'react-router';

export default class Edit extends React.Component{

constructor(props){
super(props);
this.state = {
  first_name: '',
  last_name: '',
  email: '',
  redirect: false
}
this.onChangeFirstName = this.onChangeFirstName.bind(this);
this.onChangeLastName = this.onChangeLastName.bind(this);
this.onChangeEmail = this.onChangeEmail.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}

componentDidMount(){
axios.get('http://localhost/react_crud2_api/edit.php?id='+this.props.match.params.id)
.then(response => {
  this.setState({
    first_name: response.data.first_name,
    last_name: response.data.last_name,
    email: response.data.email
  });
})
.catch(function(error){
  console.log(error);
})
}

onChangeFirstName(e){
this.setState({
  first_name: e.target.value
})
}
onChangeLastName(e){
this.setState({
  last_name: e.target.value
})
}
onChangeEmail(e){
this.setState({
  email: e.target.value
})
}
onSubmit(e){
e.preventDefault();
const obj = {
  first_name: this.state.first_name,
  last_name: this.state.last_name,
  email: this.state.email
};
//console.log(obj)
axios.post('http://localhost/react_crud2_api/update.php?id='+this.props.match.params.id, obj)
.then(this.setState({redirect: true}));
//this.props.history.push('/view');
}

render(){
// const { redirect } = this.state;
// if (redirect) {
//   return <Redirect to='/view' />;
// }
return(
  <div style={{ marginTop: 10 }}>
  <h3>Add New User</h3>
  <form onSubmit={this.onSubmit}>
    <div>
      <label>First Name</label>
      <input type="text" value={this.state.first_name} onChange={this.onChangeFirstName}  />
    </div>
    <div>
      <label>Last Name</label>
      <input type="text" value={this.state.last_name} onChange={this.onChangeLastName} />
    </div>
    <div>
      <label>Email</label>
      <input type="text" value={this.state.email} onChange={this.onChangeEmail} />
    </div>
    <div>
      <input type="submit" value="Update User" />
    </div>

  </form>
  </div>
)
}
}

Make sure you have data coming from the API in componentDidMount method.

Krina Soni
  • 870
  • 6
  • 14
  • data is coming in json format. id: "12" first_name: "gfh" last_name: "es" email: "rewr" – Vinod Jan 21 '20 at 07:09
  • 1
    Parse your json/response once it comes if it is in string format. – Krina Soni Jan 21 '20 at 07:11
  • If I write value, place of DefaultValue n form. then error comes index.js:1 Warning: A component is changing a controlled input of type text to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. – Vinod Jan 21 '20 at 07:12
  • @Vinod Look at this question. It'll solve your problem - https://stackoverflow.com/questions/47012169/a-component-is-changing-an-uncontrolled-input-of-type-text-to-be-controlled-erro – Krina Soni Jan 21 '20 at 07:15
  • 1
    Well, axios runs ,json by default. Steps you can do to debug - Add debugger in .then - check the returned values and see how you can access them in console And then set those values. Few quick suggestions as well to improve your code (better make it a habit right from the start) - use arrow functions and then you don't need to write this.functionName.bind(this) - make one function for all fields and pass the field name in function rather then making 3 functions with same piece of code e.g onChange={() => this.onChangeLastName('field_name')} - use string literals - use desctructuring – Abdul Mannan Jan 21 '20 at 07:17
  • you only need to add debugger and see how you can access the values using console. – Abdul Mannan Jan 21 '20 at 07:23
  • Where to write JSON.parse() in response? – Vinod Jan 21 '20 at 07:23
  • would be good if you can console.log() the response and share – Abdul Mannan Jan 21 '20 at 07:26
  • data is coming in json format n console.log(response.data). id: "12" first_name: "gfh" last_name: "es" email: "rewr" – Vinod Jan 21 '20 at 07:30
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/206337/discussion-between-abdul-mannan-and-vinod). – Abdul Mannan Jan 21 '20 at 07:34
1

You might be getting an array of objects in response.data I guess. You should update the API to return a single row. But to make it work as it is, may be you can do is response.data[0].first_name and it will work i guess. I think it should. Plus please make it a habit to write a cleaner code. Here are some suggestions.

  • use arrow functions and then you don't need to write this.functionName.bind(this)
  • make one function for all fields and pass the field name in function rather then making 3 functions with same piece of code e.g onChange={() => this.onChangeLastName('field_name')}
  • use string literals
  • use desctructuring
Abdul Mannan
  • 170
  • 1
  • 8