0

I am fairly new to es6, but want to recreate my jQuery code into clean es6 modules (one file per module) and drop jQuery at all. But I am already lost by binding a simple eventhandler to my buttons.

This is my currently button.js file:

import forEach from 'lodash/forEach';

export default class Buttons {
    constructor(root) {
        console.log('constructor hello');
        this.root = document.body;
        this.buttons = this.root.querySelectorAll('.default-button');
        this.bind();
    }

    bind() {
        console.log('bind hello');
        forEach(this.buttons, (button) => {
            button.addEventListener('click', () => {
                console.log('Click event just for test purpose');
            })
        })
    }
}

Here is my main.js file

class sitemodules {
    constructor() {
        sitemodules.domReady().then(this.ready.bind(this));
    }

    ready() {
        this.initButtons();
    }

    initButtons() {
        new Buttons();
    }

    static domReady() {
        return new Promise((resolve) => {
            document.addEventListener('DOMContentLoaded', resolve);
        });
    }
}

new sitemodules();

'constructor hello' and 'bind hello' are fired in the console, but I can't get the message I implemented with the click listener, thus the eventlistener seems not to be added properly.

  • First of all, if you `console.log(this.buttons)` inside the bind method, what do you get? – Daniel Mar 02 '18 at 15:54
  • You are not using the JS `forEach` iteration correctly. Please switch `forEach(...)` to `this.buttons.forEach(...)` – wmash Mar 02 '18 at 15:54
  • "*one file per module*" - you can't get around that anyway :-) maybe you meant "one class per file"? – Bergi Mar 02 '18 at 15:56
  • @wmash That won't work. this.buttons is not an array. it is a NodeList, it doesn't have a forEach method. – Daniel Mar 02 '18 at 15:56
  • 2
    You really should not use a `class` in your main module. There's no reason to create an instance of anything if it does not have a state (or at least data members). Probably not even in your `Buttons` module - a plain simple function to call would suffice. – Bergi Mar 02 '18 at 15:57
  • @Daniel That's only true for IE: https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Browser_Compatibility – Andreas Mar 02 '18 at 15:58
  • Your `Buttons` constructor expects an argument but you don't pass any – Bergi Mar 02 '18 at 15:58
  • @Daniel a `forEach` is not valid JS anyway the way OP has implemented it. OP please review [this](https://stackoverflow.com/questions/21921282/iterate-a-nodelist-using-foreach-method#30386316) for correct iteration over a NodeList – wmash Mar 02 '18 at 16:00
  • yeah, "this.buttons.forEach(..)" leads to nodeList error in the console. console.log(this.buttons) does not change anything at all. And yes, for sure, I am sorry, I meant one class per module to maintain the code properly in the future. thanks @wmash, I'll take a look –  Mar 02 '18 at 16:01
  • @DoUtDes please also consult [here](https://gist.github.com/bendc/4090e383865d81b4b684) – wmash Mar 02 '18 at 16:03
  • @wmash OP was using lodash forEach to iterate over a NodeList. It's perfectly valid: https://lodash.com/docs#forEach – Daniel Mar 02 '18 at 16:03
  • @Daniel apologies, I did not see his es6 import. My mistake – wmash Mar 02 '18 at 16:04
  • @Andreas Interesting, thanks for the update. I guess I'm still living in the past. – Daniel Mar 02 '18 at 16:06
  • To isolate the problem I adapt the code to a single element instead a nodelist and select it with querySelector. Even then I get the problem that no message is being shown on click. Maybe @Bergi is right with his advise about a missing argument in my constructor –  Mar 02 '18 at 16:14
  • @DoUtDes Put a log (or debugger breakpoint) next to the `button.addEventListener` call and see whether it runs – Bergi Mar 02 '18 at 16:17
  • Okay, I think I found the issue. The code is valid. The problem is that the button is implemented within a meganav container, which is being appended (appendChild() ) to another element when you click one of the parent links. But this happens after page load, while my code is being executed on domready –  Mar 02 '18 at 17:38

0 Answers0