freeCodeCamp: Broken state of the Todo App - needs regex escape step for ( " || ' ) on the id

Describe the Issue

When the user creates or updates the title and adds special characters ( " || ’ ) the app throws an error. Uncaught TypeError: Cannot read properties of undefined (reading 'title')

STEPS TO REPRODUCE 1:

  1. Start todo App
  2. Click on “Add New Task”
  3. On the title field add text with the quotation. Ex. “New Task”
  4. Click on “Select Task”
  5. After task created click on “Add New Task”
  6. Attempt to perform any function

ACTUAL RESULT: Nothing happens on the screen, the application entered broken state Uncaught TypeError: Cannot read properties of undefined (reading 'title')


STEPS TO REPRODUCE 2:

  1. Start todo App
  2. Click on “Add New Task”
  3. On the title field add text with the quotation. Ex. “New Task”
  4. Click on “Select Task”
  5. After task created click on an “Edit” button.

ACTUAL RESULT: Nothing happens on the screen Uncaught TypeError: Cannot read properties of undefined (reading 'title')

Affected Page

https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures-v8/learn-localstorage-by-building-a-todo-app/step-65

Your code

CODE FROM THE STEPS:

const taskObj = {
        id: `${titleInput.value.toLowerCase().split(" ").join("-")}-${Date.now()}`,
        title: titleInput.value,
        date: dateInput.value,
        description: descriptionInput.value
};

Expected behavior

EXPECTED RESULT 1:

User can add a “New Task” For the simple solution we can add a step to add replace on id under taskObj ex. :

const taskObj = {
        //Escape special characters except space (\s) and dash (-), and leave numbers and characters 
        id: `${titleInput.value.toLowerCase().replace(/[^A-Za-z0-9\-\s]/g, '').split(" ").join("-")}-${Date.now()}`,
        title: titleInput.value,
        date: dateInput.value,
        description: descriptionInput.value
};

.replace(/[^A-Za-z0-9-\s]/g, ‘’) or .replace(/[^a-z0-9-\s]/g, ‘’)

EXPECTED RESULT 2: User can modify the task

Screenshots

Without the fix: without fix With the fix: with the fix

System

  • Device: Laptop
  • OS: Windows 11 Home
  • Browser: Chrome
  • Version: 124.0.6367.61

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36

Additional context

There is other enhancement that can be made on the app, by trimming the title string to make sure it’s not empty or blank spaced. Otherwise user can create an empty title even though the field is required on HTML.

This is what I did, but I’m not good in coding yet, so I don’t feel confident to report it and give suggestions on the solution.

JS

taskForm.addEventListener('submit', (e) => {
    e.preventDefault();
    if (!isEmpty(titleInput.value)) {
        addOrUpdateTask();
    } else {
        // Create an error message element
        errorMessage.textContent = "Error: title cannot be an empty value!";
        errorMessage.style.display = "block";

        // Remove the error message after 3 seconds
        setTimeout(() => {
            errorMessage.style.display = "none";
        }, 3000);
    }
});

HTML

<div class="task-form-body">
          <label class="task-form-label" for="title-input">Title</label>
          <input required type="text" class="form-control" id="title-input" value="" />
          <label id="errorMessage" style="display: none; color: red; font-weight: bold;"></label>
          <label class="task-form-label" for="date-input">Date</label>
          <input type="date" class="form-control" id="date-input" value="" />
          <label class="task-form-label" for="description-input">Description</label>
          <textarea class="form-control" id="description-input" cols="30" rows="5"></textarea>
        </div>

About this issue

  • Original URL
  • State: open
  • Created 2 months ago
  • Reactions: 2
  • Comments: 15 (10 by maintainers)

Most upvoted comments

@code-liana

This is what I did, but I’m not good in coding yet, so I don’t feel confident to report it and give suggestions on the solution.

When reporting issues, you don’t always need to have a solution in the issue. You can just report the issue and the mods will open it up for discussion and the community can discuss different solutions. Then the mods can choose a path forward from there

For the white space and blank title I think it would be better to move it even into a separate enhancement(issue) as it seems to be completely unrelated

if you want to create a separate issue for that then that is fine

This error shows up due to an id. <div class="task" id="${id}"> is an attribute, and it messes up when we add double quotes after the equality.

Yeah, I get that.

When I initially tested it earlier, I forgot to apply the changes for the id so the error message was showing up for the title too.

It looks like then we could just apply the replace and IMO the trim too so you don’t get ids like this

Screenshot 2024-04-25 at 1 25 07 PM

so it looks like maybe this would an additional 2 steps

Hi @code-liana !

Thanks for reporting this

I think it would be better to create a separate function for removing special characters and trim the ends for whitespace That way it can be used for the id, title and description

const removeSpecialChars = (val) => {
  return val.trim().replace(/[^A-Za-z0-9\-\s]/g, '')
}

const addOrUpdateTask = () => {
  addOrUpdateTaskBtn.innerText = "Add Task";
  const dataArrIndex = taskData.findIndex((item) => item.id === currentTask.id);
  const taskObj = {
    id: `${removeSpecialChars(titleInput.value).toLowerCase().split(" ").join("-")}-${Date.now()}`,
    title:removeSpecialChars(titleInput.value) ,
    date: dateInput.value,
    description: removeSpecialChars(descriptionInput.value),
  };

As for checking for empty titles, I personally like showing an alert instead of creating a new error message and styling it

const isTitleEmpty = (val) => !val.trim().length


taskForm.addEventListener("submit", (e) => {
  e.preventDefault();

  if(isTitleEmpty(titleInput.value)){
    alert("Please provide a title")
    return
  }
  
  addOrUpdateTask();
});

let’s hear what the others think. I’ll open this up for conversation

Also, sidenote @naomi-lgbt and @Ksound22 the creation of these smaller functions would work well for what we were talking about early about updating how the breakdown of projects is done.