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('/categories/<int:id>', methods=['PATCH'])
def update_category(id):
try:
category = Category.query.get(id)
if not category:
print("serq")
return jsonify({'error': 'Category not found'}), 404
# Assuming your request body contains JSON data with the 'description' field to update
data = request.json
if 'name' in data:
category.name = data['name']
db.session.commit()
return jsonify({'message': 'Category 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
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.
Todo Series Parts:
- Part 1: Building a User-Friendly Todo App with Flask - A Step-by-Step Guide for Setting up Flask Application template
- Part 2: Building a User-Friendly Todo App with Flask - A Step-by-Step Guide for setting up our models with foreign key relationships
- Part 3: Building a User-Friendly Todo App with Flask - A Step-by-Step Guide to Performing GET Operations and Rendering Data on HTML Pages
- Part 4: Building a User-Friendly Todo App with Flask - Step-by-Step Guide to Perform Form Submissions via POST Requests
- Part 5: Building a User-Friendly Todo App with Flask - Step-by-Step Guide to Update Todo and Category Items via PATCH Requests
- Part 6: Building a User-Friendly Todo App with Flask - Step-by-Step Guide to Delete Todo and Category Items via DELETE Requests