Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript DOM Scripting By Example Improving the Application Code Next Steps

Daniel Grieve
Daniel Grieve
6,432 Points

event listener throws an error on nameActions[action] for checkbox

My code is as follows the 2 relevant event listeners

 //checkbox confirmed/unconfirmed
    ul.addEventListener('change', (event) => {

        const checkbox = event.target
        const checked = checkbox.checked
        const listItem = checkbox.parentNode.parentNode
        const label = checkbox.parentNode


        if (checked) {
            listItem.className = 'responded'
            label.childNodes[0].textContent = 'Confirmed'
            console.log(label.childNodes)
        } else {
            listItem.className = 'unanswered'
            label.childNodes[0].textContent = 'Confirm'
        }

    })

    //controls save, edit, and remove buttons
    ul.addEventListener(('click'), (event) => {

        const button = event.target
        const li = button.parentNode
        const ul = li.parentNode
        const label = li.querySelector('label')
        const span = li.querySelector('span')
        const action = button.textContent
        const nameActions = {

            edit: () => {
                const edit = document.createElement('input')
                edit.type = 'text'
                edit.value = span.textContent
                li.insertBefore(edit, label)
                li.removeChild(span)
                edit.focus()
                button.textContent = 'save'
            },

            save: () => {

                const edit = li.querySelector('input')
                const text = edit.value
                const span = document.createElement('span')
                span.textContent = text
                li.insertBefore(span, edit)
                li.removeChild(edit)
                button.textContent = 'edit'
            },

            remove: () => {
                ul.removeChild(li)
            }

        }

        nameActions[action]()

    })

The error is nameActions[action] is not a function at HTMLUListElement.ul.addEventListener

So as far as I can tell this is because there are 2 event listeners on the same 'ul'. There is no text content on the 'confirm box' so there is no action to include in the nameActions object. I tried including an action with an empty string to no success. The error doesn't impact the running of the program but I feel this is bad practice. Is there a simple fix to this problem?

1 Answer

Hey!

You seem to be calling nameActions like a function but you've created it as an object. I managed to get your code to work with a couple of if statements at the bottom like so:

ul.addEventListener(('click'), (event) => {

        const button = event.target;
        const li = button.parentNode;
        const ul = li.parentNode;
        const label = li.querySelector('label');
        const span = li.querySelector('span');
        const action = button.textContent;
        const nameActions = {

            edit: () => {
                const edit = document.createElement('input')
                edit.type = 'text'
                edit.value = span.textContent
                li.insertBefore(edit, label)
                li.removeChild(span)
                edit.focus()
                button.textContent = 'save'
            },

            save: () => {

                const edit = li.querySelector('input')
                const text = edit.value
                const span = document.createElement('span')
                span.textContent = text
                li.insertBefore(span, edit)
                li.removeChild(edit)
                button.textContent = 'edit'
            },

            remove: () => {
                ul.removeChild(li)
            }

        }

        if(event.target.textContent == 'edit') {
          nameActions.edit(event.target);
        } else if(event.target.textContent == 'save') {
          nameActions.save(event.target);
        } else if(event.target.textContent == 'remove') {
          nameActions.remove(event.target);
        }

    });

The error is gone now but the code can be optimised further. Try revisiting your projects once in a while and refactoring them to shorten your code and make it more readable/concise.

Hope this helps!

Daniel Grieve
Daniel Grieve
6,432 Points

Thanks for the reply. Funnily enough, this code is the refactored version after watching the refactoring video.