Pranay kumar
Pranay kumar

Reputation: 2197

Open bootstrap modal after axios http call in react

I made an HTTP call in react using Axios. It works perfectly fine. But when I try to open a bootstrap 4 modal after HTTP call success. It shows me an error 'modal is not a function'. I try a number of ways to solve this but unable to solve the problem. I didn't upload the whole code as it is quite long. Let me know in the comments if you want any additional code sample. Please help.


import $ from 'jquery';
import '../assets/css/signup.css';
import { Link } from 'react-router-dom';

import axios from 'axios';
import SuccessMessage from './dashboard/SuccessMessage';



class SignUp extends React.Component{
    constructor()
    {
        super()
        this.state={
            firstName:'',
            lastName:'',
            email:'',
            phoneNumber:'',
            password:'',
            confirmPassword:'',
            isSignUp:false

        }
    } 
    componentDidUpdate()
    {
       if(this.state.isSignUp === true)
       {
        let user = {
            firstName: this.state.firstName,
            lastName: this.state.lastName,
            email:this.state.email,
            phoneNumber:this.state.phoneNumber,
            password:this.state.password
        }
        console.log(user);
        var first_name = user.firstName;
        var last_name=user.lastName;
        var email=user.email;
        var phone_no=user.phoneNumber;
        var password = user.password;

        axios.post("http://ec2-14-2a9-69-0b6.us-west-2.compute.amazonaws.com:4000/dashboard/register", {
            first_name,
            last_name,
                email,
                phone_no,
                password
            }, {
                headers: header
            })
            .then(res => {
                console.log(res);
                if(res.status === 200 && res.data.success === true)
                {
                    setTimeout(() =>
                    {
                        $('#signup-success').modal('show');
                    },200)


                }
            })
       }
    }

handleSubmit=(e) =>
    {
        e.preventDefault();
        this.setState({isSignUp:true});
    }

render()
{
return(
     <SuccessMessage heading="Sign Up Successfully!" description="Please login in to access your account"  iconClass="fa fa-check bg-golden flex all-center border-radius-50"  modalId="signup-success"/>
)
}

Success Message component


<div className="modal" id={this.props.modalId}>
  <div className="modal-dialog modal-dialog-centered">

    <div className="modal-content">
    <div className="modal-header">
        <h4 className="modal-title">Modal Heading</h4>
        <button type="button" className="close" data-dismiss="modal">&times;</button>
      </div>
      <div className="modal-body align-center" style={style}>
          <i style={icon} className={this.props.iconClass} ></i>
        <h3 className="heading color-black">{this.props.heading}</h3>
        <p className="paragraph color-black">{this.props.description}</p>
      </div>
      <div className="modal-footer">
        <button type="button" className="btn btn-danger" data-dismiss="modal">Close</button>
      </div>

    </div>
  </div>
</div>

Upvotes: 2

Views: 2679

Answers (2)

Carol Skelly
Carol Skelly

Reputation: 362290

Actually getting the Bootstrap Modal to display using React (without jQuery) requires DOM manipulation. Bootstrap 4 uses jQuery to add a modal backdrop element, adds the modal-open class to the body, and finally adds display:block to the .modal wrapper.

This is why it's preferable to using reactstrap, react-bootstrap, etc... since they've already componentized the Bootstrap Modal.

If you must show (toggle) the Bootstrap Modal in React without jQuery (or other component framework), here's an example:

class SuccessMessage extends React.Component {
  constructor(props) {
    super(props);
    this.toggle = this.toggle.bind(this);
    this.state = {
        modalClasses: ['modal','fade']
    }
  }

  toggle() {
    document.body.className += ' modal-open'
    let modalClasses = this.state.modalClasses

    if (modalClasses.indexOf('show') > -1) {
        modalClasses.pop()

        //hide backdrop
        let backdrop = document.querySelector('.modal-backdrop')
        document.body.removeChild(backdrop)
    }
    else {
        modalClasses.push('show')

        //show backdrop
        let backdrop = document.createElement('div')
        backdrop.classList = "modal-backdrop fade show"
        document.body.appendChild(backdrop)
    }

    this.setState({
        modalClasses
    })
  }

  render() {
    return (
      <div
        id="messageModal"
        className={this.state.modalClasses.join(' ')}
        tabIndex="-1"
        role="dialog"
        aria-hidden="true"
        ref="messageModal"
      >
        <div className="modal-dialog modal-dialog-centered modal-lg">
          <div className="modal-content">
            <div className="modal-header">
              <h4>
                Success
              </h4>
              ...
            </div>
            <div className="modal-body">
              ...
            </div>
          </div>
        </div>
      </div>
    )
  }
}

Working Demo: https://codeply.com/p/4EV36QjwCB

Upvotes: 0

Carlos Saiz Orteu
Carlos Saiz Orteu

Reputation: 1805

Try not to use jquery and react together. You could achieve what you are saying using the react state:

class SignUp extends React.Component{
    constructor()
    {
        super()
        this.state={
            firstName:'',
            lastName:'',
            email:'',
            phoneNumber:'',
            password:'',
            confirmPassword:'',
            isSignUp:false,
            showModal: false

        }
    } 
componentDidUpdate()
{
   if(this.state.isSignUp === true)
   {
    let user = {
        firstName: this.state.firstName,
        lastName: this.state.lastName,
        email:this.state.email,
        phoneNumber:this.state.phoneNumber,
        password:this.state.password
    }
    console.log(user);
    var first_name = user.firstName;
    var last_name=user.lastName;
    var email=user.email;
    var phone_no=user.phoneNumber;
    var password = user.password;

    axios.post("http://ec2-14-2a9-69-0b6.us-west-2.compute.amazonaws.com:4000/dashboard/register", {
        first_name,
        last_name,
            email,
            phone_no,
            password
        }, {
            headers: header
        })
        .then(res => {
            console.log(res);
            if(res.status === 200 && res.data.success === true)
            {
                setTimeout(() =>
                {
                    this.setState({ showModal: true });
                },200)


            }
        })
   }
}

handleSubmit=(e) =>
    {
        e.preventDefault();
        this.setState({isSignUp:true});
    }

render()
{
return(
<div>
{
this.state.showModal &&
     <SuccessMessage heading="Sign Up Successfully!" description="Please login in to access your account"  iconClass="fa fa-check bg-golden flex all-center border-radius-50"  modalId="signup-success"/>
</div>
)
}

Also, I guess you got a display: none or something in the modal as you are doing a .show using jquery. Put that to display always as it will be only shown if the state is true.

Upvotes: 3

Related Questions