6

I have below code and i want to get the values entered in user name and password textbox and send them to node js service. But I dont know how to do that.

Things is that nothing is working. I can only render the page but functions are not working and not able to get the values as well from the textbox. I am very much new to react.

import { FormGroup} from "react-bootstrap";
import "./Login.css"
import "bootstrap/dist/css/bootstrap.min.css"

class LoginClassComponent extends React.Component {
    constructor(props) {
        super(props);
        console.log(props);
        this.state = {
            username: '',
            password: ''
        }

        this.handleTextChange = this.handleTextChange.bind(this);
        this.handleValidation = this.handleValidation.bind(this);
    }

    handleTextChange = (event) => {
        this.setState({ userName: event.target.value });
        this.setState({ password: event.target.value });
      }

    handleValidation = (event) => {
    console.log(this.props.userName);
        if (!this.state.username) {
            this.setState({ error: 'Please enter User Name' });
            event.preventDefault();
        }
        else if (!this.state.password) {
            this.setState({ error: 'Please enter Password' });
            event.preventDefault();
        }
        else {
            this.setState({ error: "" });
        }
    }

    render() {
        const {username, password} = this.props;
        return (
            <div className="Login">
                <form >
                    <FormGroup controlId="email" bsSize="large">
                        <label htmlFor="exampleInputUserName"><b>User Name</b></label>
                        <input type="username" className="form-control" id="exampleInputUserName" value={this.props.userName} onChange={this.handleTextChange} placeholder="Enter User Name"></input>
                        <div><br></br></div>
                    </FormGroup>
                    <FormGroup controlId="password" bsSize="large">
                        <label htmlFor="exampleInputPassword"><b>Password</b></label>
                        <input type="password" className="form-control" id="exampleInputPassword"  value={this.props.password} onChange={this.handleTextChange} placeholder="Enter Password"></input>
                        <div><br></br></div>
                    </FormGroup>
                    <button type="submit" onClick={this.handleValidation} className="btn btn-info">Login</button>
        &nbsp;&nbsp;&nbsp;
        <button type="submit" className="btn btn-danger">Cancel</button>
                    <div><br></br></div>
                    <div id="errorDiv">
                        {(this.state.error !== '') ? <span style={{ color: "red" }}>{this.state.error}</span> : ''}
                    </div>
                </form>
            </div>
        )
    }
}

export default LoginClassComponent;


vitosorriso
  • 765
  • 1
  • 7
  • 16
Nilesh
  • 518
  • 1
  • 9
  • 26
  • don't you get value using `this.state.username` and `this.state.password` – Muhammad Murad Haider Mar 25 '20 at 14:12
  • ` handleTextChange = (event) => { this.setState({ userName: event.target.value }); this.setState({ password: event.target.value }); } ` you are setting same value to username and password – Prakash Reddy Potlapadu Mar 25 '20 at 14:15
  • @MuhammadMuradHaider No.Now I got the value using this.props.userName in console. But after entering user name in textbox still handleValidation() function is giving an error to enter user name. Not sure what exactly I am missing here. – Nilesh Mar 25 '20 at 14:16
  • `value` attribute of textbox would just specify initial value. thats what you are getting through `this.props.userName` – Muhammad Murad Haider Mar 25 '20 at 14:18
  • try adding separate change handlers for username and password as well, you are setting both states to same value upon change – Muhammad Murad Haider Mar 25 '20 at 14:20
  • @MuhammadMuradHaider Ok. Now after adding seperate handlers I got the values from bot the text boxes. But is this the only way to do this. Suppose I have 10 textboxes then do I need to write 10 handlers for that. And my handlevalidation() is still giving me an error "Please enter User Name". Can you please help on that as well. – Nilesh Mar 25 '20 at 14:26
  • check below answer, that's a good trick to handle this, you just need to add `name` attribute with each textbox and make sure your `states` are exact match of those textboxes' names. lemme looking why validation is giving error – Muhammad Murad Haider Mar 25 '20 at 14:29
  • you are setting state as ` this.setState({ userName: event.target.value });` while your state seems to be `username` not `userName` . So, try `this.setState({ username: event.target.value });` – Muhammad Murad Haider Mar 25 '20 at 14:32
  • @MuhammadMuradHaider Ok. Solved every error now. Just to check apart from above question, how can I pass this value to node js service. Any link for that. Thanks a lot for all help. – Nilesh Mar 25 '20 at 14:39
  • sorry, i have no idea about node js service, will search for it and will post the solution if found – Muhammad Murad Haider Mar 25 '20 at 14:43
  • check this if this helps: https://stackoverflow.com/questions/42782056/pass-data-from-reactjs-to-nodejs – Muhammad Murad Haider Mar 25 '20 at 14:46
  • @MuhammadMuradHaider I have done the code in below way. I am getting values of user name and password but when I am leaving it blank my validation function is not working now. – Nilesh Mar 25 '20 at 14:54
  • can you post your edited your code please? – Muhammad Murad Haider Mar 25 '20 at 14:56
  • @MuhammadMuradHaider All working now. Thanks :) – Nilesh Mar 25 '20 at 15:20
  • to send request from your react front end to node js backend you can use `axios`. this is actually a package that you need to install in your react project `npm i axios --save`. Then you can send request to your node js service by `axios.post('[node service url]', [Data object to post]).then(function(res){..})` – Muhammad Murad Haider Mar 27 '20 at 11:24

2 Answers2

5

You can solve your problem 2 ways:

First, you can create 2 seperate onChange methods to update your username/password state

or, even better : add name tag to your form inputs:

name = userName

in your username input and

name = password

for password input.

Then make a method that triggers after onChange Event

function example(e){
   this.setState({
   [e.target.name] : [e.target.value]
  })
}

Make sure that names of your username and password forms are the same as attributes in your state.

Filip F.
  • 166
  • 8
  • Thanks a lot. This saves my couple of extra lines of unnecessary code. – Nilesh Mar 25 '20 at 14:44
  • Only thing which was giving me an error [e.target.name] = [e.target.value]. I changed it to [e.target.name] : [e.target.value] (colon instead of equal to sign. But after changing to this way my validation function is not working now. Any idea why? – Nilesh Mar 25 '20 at 14:51
  • Thanks, I will edit my answer. I was writing it without testing :) – Filip F. Mar 25 '20 at 14:53
0

You are rendering values from the props and setting values to state onChange. To work properly, you have to render value from the state as well as change values in the state. To do that, store your props values in the state in the constructor and set the value attribute to state values.

import { FormGroup} from "react-bootstrap";
import "./Login.css"
import "bootstrap/dist/css/bootstrap.min.css"

class LoginClassComponent extends React.Component {
  constructor(props) {
    super(props);
    console.log(props);
    this.state = {
        username: this.props.username,
        password: this.props.password
    }

    this.handleTextChange = this.handleTextChange.bind(this);
    this.handleValidation = this.handleValidation.bind(this);
}

handleTextChange = (event) => {
    this.setState({ [event.target.name]: event.target.value });

  }

handleValidation = (event) => {
console.log(this.props.userName);
    if (!this.state.username) {
        this.setState({ error: 'Please enter User Name' });
        event.preventDefault();
    }
    else if (!this.state.password) {
        this.setState({ error: 'Please enter Password' });
        event.preventDefault();
    }
    else {
        this.setState({ error: "" });
    }
}

render() {
    const {username, password} = this.props;
    return (
        <div className="Login">
            <form >
                <FormGroup controlId="email" bsSize="large">
                    <label htmlFor="exampleInputUserName"><b>User Name</b></label>
                    <input type="text" className="form-control" id="exampleInputUserName" value={this.state.userName} name="username" onChange={this.handleTextChange} placeholder="Enter User Name"></input>
                    <div><br></br></div>
                </FormGroup>
                <FormGroup controlId="password" bsSize="large">
                    <label htmlFor="exampleInputPassword"><b>Password</b></label>
                    <input type="password" name="password" className="form-control" id="exampleInputPassword"  value={this.state.password} onChange={this.handleTextChange} placeholder="Enter Password"></input>
                    <div><br></br></div>
                </FormGroup>
                <button type="submit" onClick={this.handleValidation} className="btn btn-info">Login</button>
    &nbsp;&nbsp;&nbsp;
    <button type="submit" className="btn btn-danger">Cancel</button>
                <div><br></br></div>
                <div id="errorDiv">
                    {(this.state.error !== '') ? <span style={{ color: "red" }}>{this.state.error}</span> : ''}
                </div>
            </form>
        </div>
    )
  }
 }
 export default LoginClassComponent;
Mohit kumar
  • 447
  • 2
  • 10