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

(JavaScript) RSVP App - Duplicate Names

My goal is to alert the user that the name they are trying to add to the list of guests already exist, but I can't wrap my head around on how to do this.

Currently, my loop checks to see if the list element is greater than 0 (checking to see if there is a list element at all). So when I run it for the 1st time, there are no list elements and the else statement just create a new list element with the necessary information. When I run it for the 2nd time it's easy because when it checks to see if there are any list elements it passes it and I have for loop to go through all the list element and get the textContent from every list element so that I can compare it to the input.value and decide whether the name is duplicate or not. The problem starts when I run it for the 3rd time. For example, let's say that these are the names of the guests in the list:

  • Mike
  • Ash

So the way my loop works is it will create a new list element when the

input.value != span.textContent

(span holds the name of the guest in the list). Let's say I try to add 'Ash' to the guest list, it will compare input.value(Ash) to the first list element(Mike), and since

Ash != Mike

it will create a new list element with that name(Ash), even tho, Ash already exists in the guest list names). So now the guest list names would look like this:

  • Mike
  • Ash
  • Ash

Because it's a for loop, it will go and create a new list element when input.value != span.textContent, and will break; on else

I can't think of a way to make this work. Here is my code:

form.addEventListener('submit', (e) => {
        e.preventDefault();

            // store the input.value to a new const text so that we can clear the text
            // from input.value
        const text = input.value;
        input.value = '';

            // check to see if there are any list elements
        if (liChildren.length > 0) {

            for (let i = 0; i < liChildren.length; i++) {
                let li = liChildren[i];
                let span = li.querySelector('span');

                if (text != span.textContent) {
                    const li = createLI(text);
                    ul.appendChild(li);
                } else {
                    console.log(`${text} already exists in the list. ${text} | ${span.textContent}`);
                    break;
                }
            }

        } else {
            const li = createLI(text);
            ul.appendChild(li);
        }       
    });

Any tips, advice, guidance would be appreciated!

Thank you!

It will be easier if you can provide a snapshot of your workspace, but i'll try to help anyway

2 Answers

First of all, I would give each name a span with a class, maybe something like invitee-name, so that your selector is a bit more robust (you may use more spans on the page, and may not want to accidentally select the wrong things.

Once you have that, do a document.querySelectorAll('invitee-name') to get a list of all these elements, of which the textContent should be the name.

Even though document.querySelectorAll() will give back a nodeList, not an array, it behaves similar to an array, so you can call the method .forEach() on it.

So you can do something like this:

const names = [];
document.querySelectorAll('.invitee-name').forEach(invitee => names.push(invitee.textContent))

now you have an array of names, so before you add a new name, you just check it like this

if (names.includes(newName)) return // this will return out of the function (which stops the function right there).
// at this point you can add the name to the list, because if it reaches this far, the name wasn't in the array

I was overthinking this so hard. ended up using this, seems to work fine

        if (names.includes(text)) {
            alert(`${text} already in list.`);
        } else {
            names.push(text);

            const li = createLI(text);
            ul.appendChild(li); 
        }

Thank you Zimri!

Don't worry, overthinking happens often.