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 trialMark Bojesen
12,873 PointsKeep getting: "nameActions[action] is not a function"
HI!
I keep getting a console error like this:
"Uncaught TypeError: nameActions[action] is not a function at HTMLUListElement.ul.addEventListener (app.js:114)"
When Guil does it in the video there seems to be no problem at all, however as the console says, we haven't declared 'action' as a function so why would we invoke it like that? Any suggestions to what I am missing? Thanks!
Code for project:
// DOM waits till page is fully loaded
document.addEventListener('DOMContentLoaded', () => {
// variables & constants
const form = document.getElementById('registrar');
const input = form.querySelector('input');
const mainDiv = document.querySelector('.main');
const ul = document.getElementById('invitedList');
const div = document.createElement('div');
const filterLabel = document.createElement('label');
const filterCheckbox = document.createElement('input');
// checkbox and the effect of hiding invitees who haven't responded.
filterLabel.textContent = "Hide those who haven't responded";
filterCheckbox.type = 'checkbox';
div.appendChild(filterLabel);
div.appendChild(filterCheckbox);
mainDiv.insertBefore(div, ul);
filterCheckbox.addEventListener('change', (e) => {
const isChecked = e.target.checked;
const lis = ul.children;
if (isChecked) {
for (let i = 0; i < lis.length; i += 1) {
let li = lis[i];
if (li.className === 'responded') {
li.style.display = ''
} else {
li.style.display = 'none';
}
}
} else {
for (let i = 0; i < lis.length; i += 1) {
let li = lis[i];
li.style.display = '';
}
}
});
function createLi(text) {
function createElement(elementName, property, value) {
const element = document.createElement(elementName);
element[property] = value;
return element;
}
function appendToLI(elementName, property, value) {
const element = createElement(elementName, property, value);
li.appendChild(element);
return element;
}
const li = document.createElement('li');
appendToLI('span', 'textContent', text);
appendToLI('label', 'textContent', 'Confirmed')
.appendChild(createElement('input', 'type', 'checkbox'));
appendToLI('button', 'textContent', 'Edit');
appendToLI('button', 'textContent', 'Remove');
return li;
}
// event handler on submit
form.addEventListener('submit', (e) => {
e.preventDefault();
const text = input.value;
input.value = '';
const li = createLi(text);
ul.appendChild(li);
});
// event handler reacts to the changed state of the checkbox
ul.addEventListener('change', (e) => {
const checkbox = event.target;
const checked = checkbox.checked;
const listItem = checkbox.parentNode.parentNode;
if (checked) {
listItem.className = 'responded';
} else {
listItem.className = '';
}
});
// buttom removes/edits added person
ul.addEventListener('click', (e) => {
if (e.target.tagName === 'BUTTON') {
const button = e.target
const li = button.parentNode;
const ul = li.parentNode;
const action = button.textContent;
const nameActions = { /* nameActions object */
remove: () => {
ul.removeChild(li);
},
edit: () => {
const span = li.firstElementChild;
const input = document.createElement('input');
input.type = 'text';
input.value = span.textContent;
li.insertBefore(input, span);
li.removeChild(span);
button.textContent = 'Save';
},
save: () => {
const input = li.firstElementChild;
const span = document.createElement('span');
span.textContent = input.value;
li.insertBefore(span, input);
li.removeChild(input);
button.textContent = 'Edit';
}
};
// select and run action in button's name
nameActions[action](); /* <-- Line 114 */
}
});
});
Any help is much appreciated, thanks!
1 Answer
Steven Parker
231,275 PointsThere's no function named "action".
Instead, action should contain the name of one of the functions ("remove", "edit", or "save").
But when you create the buttons, the names you place on them have capital first letters, so they don't match the names of the functions. You could change either the button texts or the function names, or you could change the case when you assign the variable:
const action = button.textContent.toLowerCase();
Mark Bojesen
12,873 PointsMark Bojesen
12,873 PointsAHA! Thanks a lot Steven, that's really quite obvious now you point it out!
Kieran Barker
15,028 PointsKieran Barker
15,028 PointsThanks, Steven :)
Anton Kilk
Full Stack JavaScript Techdegree Student 11,256 PointsAnton Kilk
Full Stack JavaScript Techdegree Student 11,256 PointsThank you!