whoisearth
whoisearth

Reputation: 4170

Uncaught TypeError: Cannot read property 'showModal' of null

I'm attempting to take the following code here and refactor the login into a modal. Unfortunately when clicking Login I get the following error:

Uncaught TypeError: Cannot read property 'showModal' of null

Here is my Navigation.js

import React, { Component, PropTypes } from 'react';
import { Button, Modal, Nav, Navbar } from 'react-bootstrap';
import { IndexLinkContainer } from 'react-router-bootstrap';
import Login from '../Login/Login';
import Logout from '../Logout/Logout';
import { loginUser, logoutUser } from '../../actions/actions'
import './Navigation.css'

export default class Navigation extends Component {

    constructor(props, context) {
        super(props, context);

        this.state = {
            showModal: false
        };
    }

    open() {
        this.showModal.setState = true
    }

    close() {
        this.showModal.setState = false
        }

    render() {

        const { dispatch, isAuthenticated, errorMessage } = this.props;


        return (
            <div>
                <Navbar className="navbar navbar-default navbar-fixed-top">
                    <Navbar.Header>
                        <Navbar.Brand>
                            <IndexLinkContainer to="/"><a href="/">myApp</a></IndexLinkContainer>
                        </Navbar.Brand>
                        <Navbar.Toggle />
                    </Navbar.Header>
                    <Navbar.Collapse>
                        <Nav pullRight>

                            {!isAuthenticated &&
                            <Button bsStyle="primary" onClick={this.open}>Login</Button>
                            }

                            {isAuthenticated &&
                            <Logout onLogoutClick={() => dispatch(logoutUser())} />
                            }

                        </Nav>
                    </Navbar.Collapse>
                </Navbar>

                <Modal show={this.state.showModal} onHide={this.close}>
                    <Modal.Header closeButton>
                        <Modal.Title>Login</Modal.Title>
                    </Modal.Header>
                    <Modal.Body>
                        <Login
                            errorMessage={errorMessage}
                            onLoginClick={ creds => dispatch(loginUser(creds)) }
                        />
                    </Modal.Body>
                </Modal>
            </div>
        )
    }

}

Navigation.propTypes = {
    dispatch: PropTypes.func.isRequired,
    isAuthenticated: PropTypes.bool.isRequired,
    errorMessage: PropTypes.string,
}

The page loads fine but my modal isn't launching from clicking the button. I'm using react and react-bootstrap.

Upvotes: 0

Views: 9051

Answers (1)

ZekeDroid
ZekeDroid

Reputation: 7209

Right so you have several bugs in your code:

When using an ES6 class as you are doing here, your methods do not autobind meaning that if you have an event handler on your JSX like this.open, then this is the wrong context therefore anything you do in the function will not be able to use this. To fix, bind somewhere, preferably in the constructor but can be done inline:

onClick={this.open.bind(this)}

Second issue is that the function itself is doing something kind of random. Of course this.showModal throws an error because of the binding issue mentioned above, but even with the binding, that is not how you access/set state variables. Instead, switch to:

this.setState({ showModal: true }) // or false for `close`

It should then start working properly.

Upvotes: 3

Related Questions