Search code examples
javascriptcssreactjsmaterialize

React-materialize-css Modals not working because it cannot read Modal class of M


So i have been trying to get modals to work in multiple ways, plain javascript/react, react-modal and materialize-css. Now with materialize-css it looks like it almost works but doesn't, I get the following error:

projects.js:16 Uncaught TypeError: Cannot read property 'Modal' of undefined
    at HTMLDocument.<anonymous>

I have googled around to no avail. Also i did try to use jQuery but that also did not work.

my code:

import React, { Component } from 'react';
import Link from 'react-router-dom';
import "./projects.css";
import helper from "../../Helpers/helpers";
import ReactDOM from 'react-dom'
import M from 'react-materialize'

document.addEventListener('DOMContentLoaded', function() {
    var elems = document.getElementById('modal1');
    var options = {};
    var instance = M.Modal.init(elems);
    instance.open();
});

class Projects extends Component {
    constructor() {
        super();
        this.state = {
            projects: [],
            name: '',
            description: ''
        };
    }

    componentDidMount() {}

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

    userIsAdmin = (project, user) => {};

    userIsOwner = (project, user) => {};

    onSubmit = event => {};

    deleteProject(projectId) {};

    editProject(projectId) {}

    render() {
        const projects = this.state.projects;
        return (
            <div className={'margin container row'}>
                <div className={"col s12"}>
                    <div className={'card'}>
                        <div className={'card-content'} id={'projectsCard'}>
                            <h4 className={'card-title'}>Uw projecten</h4>
                            <div id="modal1" className={"modal"}>
                                <div className="modal-content">
                                    <h4>Modal Header</h4>
                                    <p>A bunch of text</p>
                                </div>
                                <div className="modal-footer">
                                    <a href="#modal1" className="modal-close waves-effect waves-green btn-flat">Agree</a>
                                </div>
                            </div>
                            <table className={"highlight"}>
                                <thead>
                                    <tr>
                                        <th>Project naam</th>
                                        <th>Project beschrijving</th>
                                        <th>project opties</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    {projects.map(project =>
                                        this.userIsOwner(project,user)

                                        // If the current user is a owner of a project show 
                                        ?
                                            <tr className={'collection-item'} key={project._id}>
                                                <td><a href={'/project/' + project._id}>{project.name}</a></td>
                                                <td>{project.description}</td>
                                                <td>
                                                    <a className="waves-effect waves-light btn modal-trigger material-icons"
                                                       href="#modal1">delete</a>
                                                </td>
                                            </tr>
                                        :
                                            this.userIsAdmin(project,user)
                                            ?
                                                <tr className={'collection-item'} key={project._id}>
                                                    <td><a href={'/project/' + project._id}>{project.name}</a></td>
                                                    <td>{project.description}</td>
                                                    <td></td>
                                                </tr>
                                            :
                                                <tr className={'collection-item'} key={project._id}>
                                                    <td><a href={'/project/' + project._id}>{project.name}</a></td>
                                                    <td>{project.description}</td>
                                                    <td></td>
                                                </tr>
                                    )}
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                <div className={"col s12"}>
                    <div className={'card'}>
                        <div className={'card-content'}>
                            <h4 className={'card-title'}>Maak een project aan</h4>
                            <div>
                                <form onSubmit={this.onSubmit}>
                                    <div className={"input-field col s6"}>
                                        <input placeholder={"Projects naam *"} id={"projectName"} type={"text"} name={'name'} className={"validate blue-text"} value={this.state.name} onChange={this.handleChange}/>
                                        <label htmlFor={"projectName"} className={"blue-text"}>Project naam</label>
                                    </div>
                                    <div className={"input-field col s6"}>
                                        <input placeholder={"Projects beschrijving *"} id={"ProjectDesc"} type={"text"} name={'description'} className={"validate blue-text"} value={this.state.description} onChange={this.handleChange}/>
                                        <label htmlFor={"projectDesc"} className={"blue-text"}>Project beschrijving</label>
                                    </div>
                                    <button className="btn waves-effect waves-light" type="submit">
                                        Submit
                                        <i className="material-icons right">send</i>
                                    </button>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}


export default Projects;

and my package.json:

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "react-materialize": "^3.4.1",
    "react-router-dom": "^5.1.2",
    "react-scripts": "0.9.x"
  },
  "devDependencies": {},
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:5001"
}

My question: How would i go about fixing this? My knowledge about react/materialize has run out.


Solution

  • Primo, It's look that you don't use the react-material in the good way...

    You don't have to use the native materialize javascript in a react app...

    Look at here : http://react-materialize.github.io/react-materialize/?path=/story/react-materialize--welcome && http://react-materialize.github.io/react-materialize/?path=/story/javascript-modal--fixed-footer

    If you go on the info tab, you'll see than there is a property 'show' if you want to display it in open state at the component mount...

    Secundo, if you use the native js document.ready and want to use the 'M' variable, have you include the native materialize inside your index.html ?