Search code examples
reactjsreact-routerbootstrap-modalreact-router-domreact-props

Redirect React Router Route From onClick in Modal


Below is code for the body of a sign up modal. How I would like it to work would be the user enters credentials and when they click submit they are automatically taken to the route "/secret" which is their dashboard.

Currently, when the user clicks submit an error is thrown and the alert "('Error logging in please try again')" appears. I only want this to happen if there is an error with their input (i.e. nonunique entry, not hitting requirements ect.)

This alert is thrown every time the user clicks submit regardless if the input hits requirements and is pushed to the database. Also for some reason react seems to over look the line of code to redirect the user to the desired route.

if (res.status === 200) 
{  this.props.history.push('/secret'); 
} 

Is there a way to redirect the route if I receive a res.status === 200 while also keeping the condition to throw the error if it occurs?

signup.js (modal body)

import React, { Component } from 'react';
import API from "../utils/API.js";
import { Container, Row, Col, Button, Alert, Modal, ModalHeader, ModalBody, ModalFooter, Label, Input } from 'reactstrap';
export default class Signup extends Component {
  constructor(props) {
    super(props)
    this.state = {
      email: '',
      password: '',
      username: ''
    };
  }
  handleInputChange = (event) => {
    const { value, name } = event.target;
    this.setState({
      [name]: value
    });
  }
  onSubmit = (event) => {
    event.preventDefault();
    API.signUpUser(this.state.email, this.state.username, this.state.password)
   
      .then(res => {
        if (res.status === 200) {
          this.props.history.push('/secret');
        } else {
          const error = new Error(res.error);
          throw error;
        }
      })
      .catch(err => {
        console.error(err);
        alert('Error logging in please try again');
      });
  }
  render() {
    console.log(this.state)
    return (
      <form onSubmit={this.onSubmit}>

        Email: <input
          type="email"
          name="email"
          placeholder="Enter email"
          value={this.state.email}
          onChange={this.handleInputChange}
          required
        />
        <br></br>
        <br></br>

        Username: <input
          type="text"
          name="username"
          placeholder="Enter username"
          value={this.state.username}
          onChange={this.handleInputChange}
          required
        />
        <br></br>
        <br></br>


        Password: <input
          type="password"
          name="password"
          placeholder="Enter password"
          value={this.state.password}
          onChange={this.handleInputChange}
          required
        />
         <br></br>
        <br></br>
        <Button type="submit" value="Submit" color="primary" className="btn btn-warning">Sign Up</Button>

      
      </form>
    );
  }
}

app.js (react routes)

 <Switch>
            <Route path="/" exact component={Home} />
            <Route path="/hometwo" exact component={Home2} />
            <Route path="/secret" component={withAuth(Secret)} />
            <Route path="/login" component={Login} />
            <Route path="/signup" component={Signup} />
            <Route path="/signout" component={Signout} />
            <Route path="/loggedIn" component={withAuth(loggedIn)} />
          </Switch>

Signup User API

  signUpUser: function (email, username, password) {

    const signUpURL = "/api/user"
    // console.log("username " + username + "password " + password)
    return axios.post(signUpURL, { email,username, password }).then(result => result.data);
    // return axios.post(signUpURL, { email, username, password }).then(result => result.data);
    // .then(result => result.data);

  },

NEW Signup.js


import React, { Component } from 'react';
import API from "../utils/API.js";
import { Container, Row, Col, Button, Alert, Modal, ModalHeader, ModalBody, ModalFooter, Label, Input } from 'reactstrap';
export default class Signup extends Component {
  constructor(props) {
    super(props)
    this.state = {
      email: '',
      password: '',
      username: '',
 
    };
  }
  handleInputChange = (event) => {
    const { value, name } = event.target;
    this.setState({
      [name]: value
    });
  }
  onSubmit = (event) => {
    event.preventDefault();
    // API.signUpUser(this.state.email, this.state.username, this.state.password)

      fetch('/api/authenticatesignup', {
          method: 'POST',
          body: JSON.stringify(this.state),
          headers: {
            'Content-Type': 'application/json'
          }
        })
      .then(res => {
        console.log("THIS IS res " + JSON.stringify(res.status));
        if (res.status === 200) {

          // alert("You can now go to your dashboard")
          // window.location.reload();

          // // alert("You can now go to your dashboard")
          this.props.history.push('/secret')
        } else {
          const error = new Error(res.error);
          // console.log("This is error on client side " + error)
          throw error;
          // alert('Error logging in please try again');

        }
      })
      .catch(err => {
        console.error(err);
        alert('Error logging in please try again');
      });
  }
  render() {
    console.log(this.state)
    return (
      <form onSubmit={this.onSubmit}>

        Email: <input
          type="email"
          name="email"
          placeholder="Enter email"
          value={this.state.email}
          onChange={this.handleInputChange}
          required
        />
        <br></br>
        <br></br>

        Username: <input
          type="text"
          name="username"
          placeholder="Enter username"
          value={this.state.username}
          onChange={this.handleInputChange}
          required
        />
        <br></br>
        <br></br>


        Password: <input
          type="password"
          name="password"
          placeholder="Enter password"
          value={this.state.password}
          onChange={this.handleInputChange}
          required
        />
        <br></br>
        <br></br>
        <Button type="submit" value="Submit" color="primary" className="btn btn-warning">Sign Up</Button>


      </form>
    );
  }
}

API endpoint of signup in server

//authenticate checker signup
app.post('/api/authenticatesignup', function (req, res) {
  const { email, username, password } = req.body;
  User.create({
    email: req.body.email,
    username: req.body.username,
    password: req.body.password
  }, 
  
  function (err, user) {
    if (err) {
      console.error(err);
      res.status(500)
        .json({
          error: 'Internal error please try again'
        });
    }
    else {
      // Issue token
      const payload = { username };
      const token = jwt.sign(payload, secret, {
        expiresIn: '1h'
      });
      res.cookie('token', token, { httpOnly: true })
        .sendStatus(200);
        console.log("New USER!" + req.body.email + req.body.password)
    }
  })


});

res.status


Solution

  • You need to wrap the component with withRouter.

    You can get access to the history object’s properties and the closest 's match via the withRouter higher-order component. withRouter will pass updated match, location, and history props to the wrapped component whenever it renders.

    import React, { Component } from 'react';
    import { withRouter } from "react-router";
    import API from "../utils/API.js";
    import { Container, Row, Col, Button, Alert, Modal, ModalHeader, ModalBody, ModalFooter, Label, Input } from 'reactstrap';
    
    class SignupComp extends Component {
        constructor(props) {
            super(props)
            this.state = {
                email: '',
                password: '',
                username: '',
    
            };
        }
        handleInputChange = (event) => {
            const { value, name } = event.target;
            this.setState({
                [name]: value
            });
        }
        onSubmit = (event) => {
            event.preventDefault();
            // API.signUpUser(this.state.email, this.state.username, this.state.password)
            fetch('/api/authenticatesignup', {
                method: 'POST',
                body: JSON.stringify(this.state),
                headers: {
                    'Content-Type': 'application/json'
                }
            })
                .then(res => {
                    console.log("THIS IS res " + JSON.stringify(res.status));
                    if (res.status === 200) {
                        // alert("You can now go to your dashboard")
                        // window.location.reload();
                        // // alert("You can now go to your dashboard")
                        this.props.history.push('/secret')
                    } else {
                        const error = new Error(res.error);
                        // console.log("This is error on client side " + error)
                        throw error;
                        // alert('Error logging in please try again');
                    }
                })
                .catch(err => {
                    console.error(err);
                    alert('Error logging in please try again');
                });
        }
        render() {
            console.log(this.state)
            return (
                <form onSubmit={this.onSubmit}>
                    Email: <input
                        type="email"
                        name="email"
                        placeholder="Enter email"
                        value={this.state.email}
                        onChange={this.handleInputChange}
                        required
                    />
                    <br></br>
                    <br></br>
                    Username: <input
                        type="text"
                        name="username"
                        placeholder="Enter username"
                        value={this.state.username}
                        onChange={this.handleInputChange}
                        required
                    />
                    <br></br>
                    <br></br>
    
                    Password: <input
                        type="password"
                        name="password"
                        placeholder="Enter password"
                        value={this.state.password}
                        onChange={this.handleInputChange}
                        required
                    />
                    <br></br>
                    <br></br>
                    <Button type="submit" value="Submit" color="primary" className="btn btn-warning">Sign Up</Button>
    
                </form>
            );
        }
    }
    
    const Signup = withRouter(SignupComp);
    export default Signup;