Part 5: Building a User-Friendly Todo App with Flask - Step-by-Step Guide to Update Todo and Category Items via PATCH Requests

Hey everyone, welcome to the fifth part of my Flask-based basic todo application series. In this post, I'll guide you through updating your todo and category items via PATCH requests in your Flask todo app.

Remember in part three, there were onclick functions within our script tags. In this part, we'll primarily focus on these functions.

For Todo Items:

Replace the existing makeEditable function with this code:

function makeEditable(todoId) {
    // Get the element representing the todo description using its unique ID
    const todoDescription = document.getElementById(`todoDescription_${todoId}`);
    
    // Capture the existing text content of the todo description
    const descriptionText = todoDescription.textContent;
    
    // Create a new input field dynamically
    const inputField = document.createElement('input');
    inputField.type = 'text';
    inputField.value = descriptionText;
    
    // Add CSS classes to the input field for styling
    inputField.classList.add('border', 'border-gray-300', 'rounded-md', 'p-1');
    
    // Listen for 'Enter' key press event on the input field
    inputField.addEventListener('keyup', function(event) {
        // When 'Enter' key is pressed, trigger the updateTodoDescription function
        if (event.key === 'Enter') {
            updateTodoDescription(todoId, inputField.value);
        }
    });
    
    // Replace the original todo description element with the created input field
    todoDescription.replaceWith(inputField);
    
    // Set focus on the input field to enable immediate editing of the todo description
    inputField.focus();
}

This code allows editing of a todo item when the edit icon is clicked.

Next, replace the updateTodoDescription function with this code:

function updateTodoDescription(todoId, newDescription) {
    // Perform an API request to update the todo description
    fetch(`/todos/${todoId}`, {  // Make a PATCH request to the specified todo ID
        method: 'PATCH',  // Using the PATCH method for partial update
        headers: {
            'Content-Type': 'application/json'  // Specify the request body as JSON
        },
        body: JSON.stringify({ description: newDescription })  // Set the new description in the request body
    })
    .then(response => {
        if (response.ok) {  // Check if the response status is successful
            console.log(`Todo with ID ${todoId} description updated`);  // Log a success message
            window.location.reload(); // Refresh the page to reflect changes
        } else {
            console.error('Error updating todo description', response.statusText);  // Log an error if not successful
        }
    })
    .catch(error => {
        console.error('Error:', error);  // Catch and log any errors during the API request
    });
}

This function updates a todo item after editing.

In your app.py file, add the following route for updating todo items:

@app.route('/todos/<int:id>', methods=['PATCH'])
def update_todo(id):
    try:
        # Fetch the todo with the specified ID from the database
        todo = Todo.query.get(id)
        
        # Check if the todo exists
        if not todo:
            return jsonify({'error': 'Todo not found'}), 404  # Return a 404 error if todo not found
        
        # Assuming your request body contains JSON data with the 'description' field to update
        data = request.json
        
        # Check if the 'description' field is present in the request data
        if 'description' in data:
            # Update the description of the todo with the new value
            todo.description = data['description']
        
        db.session.commit()  # Commit changes to the database
        
        # Return a success message upon successful update
        return jsonify({'message': 'Todo updated successfully'}), 200
    
    except Exception as e:
        db.session.rollback()  # Rollback changes if an exception occurs
        return jsonify({'error': str(e)}), 500  # Return an error response with status code 500 for any exceptions

This route allows updating todo items. Refresh the page and try editing todo items for changes to take effect.

For Category Items:

Replace the existing makeCategoryEditable function with this code:

function makeCategoryEditable(categoryId) {
  // Get the category element using its ID
  const category = document.getElementById(`category_${categoryId}`);
  
  // Get the current text content of the category element
  const descriptionText = category.textContent;
  
  // Create a new input field element
  const inputField = document.createElement('input');
  inputField.type = 'text';
  inputField.value = descriptionText;
  
  // Add CSS classes to the input field for styling
  inputField.classList.add('border', 'border-gray-300', 'rounded-md', 'p-1');
  
  // Add an event listener for 'keyup' events on the input field
  inputField.addEventListener('keyup', function(event) {
    // If 'Enter' key is pressed
    if (event.key === 'Enter') {
      // Call the updateCategoryName function with the category ID and input value
      updateCategoryName(categoryId, inputField.value);
    }
  });
  
  // Replace the category element with the input field in the DOM
  category.replaceWith(inputField);
  
  // Focus on the newly created input field
  inputField.focus();
}

This code enables editing of a category item when the edit icon is clicked.

Next, replace the updateCategoryName function with this code:

function updateCategoryName(categoryId, newName) {
  // Perform a PATCH request to update the category name using the provided category ID
  fetch(`/categories/${categoryId}`, {
    method: 'PATCH', // Using the PATCH method for updating
    headers: {
      'Content-Type': 'application/json' // Setting content type as JSON
    },
    body: JSON.stringify({ name: newName }) // Sending the new name in JSON format
  })
  .then(response => {
    // If the response is successful (status code 200-299)
    if (response.ok) {
      console.log(`Category with ID ${categoryId} name updated`); // Log success message
      window.location.reload(); // Refresh the page to reflect changes
    } else {
      console.error('Error updating category name', response.statusText); // Log error message
    }
  })
  .catch(error => {
    console.error('Error:', error); // Log any catch error
  });
}

This function updates a category item after editing.

Add the route for updating category items in your app.py file:

@app.route('/todos/<int:id>', methods=['PATCH'])
def update_todo(id):
    try:
        # Fetch the todo with the specified ID from the database
        todo = Todo.query.get(id)
        
        # Check if the todo exists
        if not todo:
            return jsonify({'error': 'Todo not found'}), 404  # Return a 404 error if todo not found
        
        # Assuming your request body contains JSON data with the 'description' field to update
        data = request.json
        
        # Check if the 'description' field is present in the request data
        if 'description' in data:
            # Update the description of the todo with the new value
            todo.description = data['description']
        
        db.session.commit()  # Commit changes to the database
        
        # Return a success message upon successful update
        return jsonify({'message': 'Todo updated successfully'}), 200
    
    except Exception as e:
        db.session.rollback()  # Rollback changes if an exception occurs
        return jsonify({'error': str(e)}), 500  # Return an error response with status code 500 for any exceptions

This route allows updating category items. Refresh the page and try editing category items for changes to take effect.

That's all for this tutorial! Check out the video below for a visual walkthrough of these processes.

Author
author-image

Hello, my name is Abubakar Zakari. Am a budding fullstack developer from Nigeria who loves developing softwares and learning new frameworks and langauges.

Comment

Select image


Comments
No comment yet

DEVMAESTERS

Newsletter

Services

Frontend Development |Backend Development |Full Website Development |Bootstrap Website upgrades | Website Debbugging | Website Hosting & deployment

Contact

Interested in hiring me or collaborating with me on a project, click on any of the links below to get my social media handle

Or contact me via Tel: (+234)-806-225-7480 | Email: abubakarzakari1703@gmail.com

Copywright@devmaesters.com
Privacy Policy

By using our website,
you agree that devmaesters can store cookies on your device and disclose information in accordance with our privacy policy.