-
-
Notifications
You must be signed in to change notification settings - Fork 144
West Midlands | 25-ITP-Sep | Ali Naru | Sprint 2 | feature/BookLibrary #334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
… storage handling
|
Your PR's title isn't in the expected format. Please check the expected title format, and update yours to match. Reason: Wrong number of parts separated by |s If this PR is not coursework, please add the NotCoursework label (and message on Slack in #cyf-curriculum or it will probably not be noticed). If this PR needs reviewed, please add the 'Needs Review' label to this PR after you have resolved the issues listed above. |
|
Your PR couldn't be matched to an assignment in this module. Please check its title is in the correct format, and that you only have one PR per assignment. If this PR is not coursework, please add the NotCoursework label (and message on Slack in #cyf-curriculum or it will probably not be noticed). If this PR needs reviewed, please add the 'Needs Review' label to this PR after you have resolved the issues listed above. |
2 similar comments
|
Your PR couldn't be matched to an assignment in this module. Please check its title is in the correct format, and that you only have one PR per assignment. If this PR is not coursework, please add the NotCoursework label (and message on Slack in #cyf-curriculum or it will probably not be noticed). If this PR needs reviewed, please add the 'Needs Review' label to this PR after you have resolved the issues listed above. |
|
Your PR couldn't be matched to an assignment in this module. Please check its title is in the correct format, and that you only have one PR per assignment. If this PR is not coursework, please add the NotCoursework label (and message on Slack in #cyf-curriculum or it will probably not be noticed). If this PR needs reviewed, please add the 'Needs Review' label to this PR after you have resolved the issues listed above. |
cjyuan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
There are some
console.log()statements left in your code. If they are not needed for the app to function, you should remove them to make the code clean. -
Can you check if any of this general feedback can help you further improve your code?
https://github.com/cjyuan/Module-Data-Flows/blob/book-library-feedback/debugging/book-library/feedback.md
Doing so can help me speed up the review process. Thanks.
…nd input validation
I have now reviewed and refactored these changes, please review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR refactors and debugs a book library application, fixing several critical bugs and improving code quality. The changes modernize the JavaScript code with better practices while maintaining functionality.
Key changes:
- Fixed bugs including incorrect variable references (e.g.,
title.valueinstead ofauthor.value), missing parentheses in loops, and typo in event listener names - Refactored the render function to use modern DOM manipulation with
forEachand event delegation patterns - Added input validation with trimming and proper type conversion, plus form clearing after submission
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
| debugging/book-library/script.js | Fixed multiple bugs, refactored render logic with modern JavaScript patterns, improved variable naming, and added input validation and form clearing |
| debugging/book-library/index.html | Added semantic HTML attributes (lang, title), corrected input types from custom to standard text/number, changed script loading to module type, and improved code formatting |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
debugging/book-library/index.html
Outdated
| class="form-control" | ||
| id="pages" | ||
| name="pages" | ||
| required |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HTML input type is number, but the JavaScript parses it with parseInt(). While this works, it's redundant since number inputs already return numeric strings. The HTML5 number input also doesn't prevent negative values by default. Consider adding a min="1" attribute to the pages input in the HTML to enforce positive values at the form level.
| required | |
| required | |
| min="1" |
debugging/book-library/script.js
Outdated
| if (!title || !author || isNaN(pages)) { | ||
| alert("Please fill all fields correctly!"); |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validation doesn't check for negative page numbers or zero pages. Consider adding validation: if (!title || !author || isNaN(pages) || pages <= 0) to ensure meaningful book data is stored.
| if (!title || !author || isNaN(pages)) { | |
| alert("Please fill all fields correctly!"); | |
| if (!title || !author || isNaN(pages) || pages <= 0) { | |
| alert("Please fill all fields correctly! Page number must be a positive integer."); |
debugging/book-library/script.js
Outdated
| myLibrary.splice(i, 1); | ||
| document.querySelectorAll(".delete-book").forEach(button => { | ||
| button.addEventListener("click", (e) => { | ||
| const index = e.target.dataset.index; |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The dataset.index property returns a string. While JavaScript will coerce this string to a number when used with splice(), it's better to be explicit about type conversions. Consider: const index = parseInt(e.target.dataset.index, 10);
debugging/book-library/index.html
Outdated
| <th>Author</th> | ||
| <th>Number of Pages</th> | ||
| <th>Read</th> | ||
| <th></th> |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The last table header is empty (<th></th>), which is poor for accessibility. Screen readers won't announce what this column represents. Consider adding appropriate text like "Actions" or visually hiding it with <th><span class="sr-only">Actions</span></th> using Bootstrap's sr-only class.
| <th></th> | |
| <th><span class="sr-only">Actions</span></th> |
debugging/book-library/script.js
Outdated
| // Add event listeners for buttons | ||
| document.querySelectorAll(".toggle-read").forEach(button => { | ||
| button.addEventListener("click", (e) => { | ||
| const index = e.target.dataset.index; |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The dataset.index property returns a string. While JavaScript will coerce this string to a number when used with array indexing, it's better to be explicit about type conversions. Consider: const index = parseInt(e.target.dataset.index, 10);
debugging/book-library/script.js
Outdated
| document.querySelectorAll(".toggle-read").forEach(button => { | ||
| button.addEventListener("click", (e) => { | ||
| const index = e.target.dataset.index; | ||
| myLibrary[index].check = !myLibrary[index].check; | ||
| render(); | ||
| }); | ||
| }); |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Event listeners are being re-added every time render() is called, which can cause performance issues and unexpected behavior. Since the table is completely regenerated each time (line 64 clears innerHTML), the old event listeners are removed with the DOM elements, but this approach is inefficient.
Consider using event delegation by attaching a single event listener to the table or tbody instead:
tbody.addEventListener("click", (e) => {
if (e.target.classList.contains("toggle-read")) {
const index = parseInt(e.target.dataset.index, 10);
myLibrary[index].check = !myLibrary[index].check;
render();
}
});
debugging/book-library/script.js
Outdated
| // Display a non-blocking notification | ||
| const notification = document.createElement("div"); | ||
| notification.textContent = "Book deleted successfully."; | ||
| notification.className = "notification"; | ||
| document.body.appendChild(notification); | ||
|
|
||
| // Remove the notification after 3 seconds | ||
| setTimeout(() => { | ||
| notification.remove(); | ||
| }, 3000); |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The notification element is created and added after calling render(), which means if render() throws an error, the user won't see the notification. Additionally, multiple rapid deletions will create multiple notification elements that aren't cleaned up properly. Consider moving the notification display before render() or implementing a notification queue system to handle multiple notifications gracefully.
cjyuan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good idea to get a second opinion at the code from AI.
I am sure there is a way to use it outside the scope of a PR so that the AI messages won't interfere with the review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are errors in the HTML code. Please fix them.
debugging/book-library/script.js
Outdated
| const notification = document.createElement("div"); | ||
| notification.textContent = "Book deleted successfully."; | ||
| notification.className = "notification"; | ||
| document.body.appendChild(notification); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach is better than using alert() for showing notification.
Please note that when the notification is added to the bottom of the page, there is a chance that the user won't see the message when there are too many books on the list. (Change is optional as this is not part of the original implementation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
debugging/book-library/index.html
Outdated
| type="button" | ||
| value="Submit" | ||
| class="btn btn-primary" | ||
| onclick="submit();" |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using inline event handlers like onclick="submit();" is considered a bad practice and violates Content Security Policy (CSP) best practices. Consider moving this to an event listener in the JavaScript file: document.querySelector('input[type="button"]').addEventListener('click', submit);
| onclick="submit();" |
debugging/book-library/script.js
Outdated
| this.title = title; | ||
| this.author = author; | ||
| this.pages = pages; | ||
| this.check = check; |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property name check in the Book constructor is ambiguous. It should be renamed to something more descriptive like isRead or hasBeenRead to clearly indicate what it represents. This would make the code more self-documenting.
debugging/book-library/index.html
Outdated
| <meta | ||
| charset="utf-8" | ||
| name="viewport" | ||
| content="width=device-width, initial-scale=1.0" | ||
| /> | ||
| /> |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The meta tag has invalid HTML structure. The charset and viewport attributes cannot be combined in a single meta tag. They should be split into two separate tags:
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
debugging/book-library/script.js
Outdated
| const titleInput = document.getElementById("title"); | ||
| const authorInput = document.getElementById("author"); | ||
| const pagesInput = document.getElementById("pages"); | ||
| const readCheckbox = document.getElementById("check"); |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The script is loaded with type="module", which creates a module scope. However, the window.submit = submit; assignment at the end of script.js won't work reliably because the DOM elements (titleInput, authorInput, etc.) are queried at the top level before the DOM is fully loaded. These queries happen immediately when the script loads, but the elements don't exist yet. Move the DOM element queries inside the submit() function or into a DOMContentLoaded event handler.
debugging/book-library/script.js
Outdated
| // Add event listeners for buttons | ||
| document.querySelectorAll(".toggle-read").forEach(button => { | ||
| button.addEventListener("click", (e) => { | ||
| const index = e.target.dataset.index; |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dataset.index returns a string, not a number. When using myLibrary[index] with a string index on an array, it still works due to JavaScript's type coercion, but it's better practice to convert it to a number explicitly: const index = parseInt(e.target.dataset.index, 10);. This ensures proper array indexing and prevents potential bugs if the array is later used in contexts where type matters.
debugging/book-library/script.js
Outdated
| document.querySelectorAll(".delete-book").forEach(button => { | ||
| button.addEventListener("click", (e) => { | ||
| const index = e.target.dataset.index; | ||
| myLibrary.splice(index, 1); | ||
| render(); | ||
|
|
||
| // Display a non-blocking notification | ||
| const notification = document.createElement("div"); | ||
| notification.textContent = "Book deleted successfully."; | ||
| notification.className = "notification"; | ||
| document.body.appendChild(notification); | ||
|
|
||
| // Remove the notification after 3 seconds | ||
| setTimeout(() => { | ||
| notification.remove(); | ||
| }, 3000); | ||
| }); | ||
| } | ||
| }); |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every time render() is called, new event listeners are attached to all delete buttons. This creates memory leaks as old listeners aren't removed. Use event delegation instead by attaching a single listener to the table element.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Hi CJ I have refactored changes, I did not meant to intentionally add copilot as a reviewer, I don't have access to remove it, please can you remove it as a reviewer with Admin access, thanks |
|
According the W3C validator, your HTML code still have errors. |
…input validation, and styling
|
@copilot open a new pull request to apply changes based on the comments in this thread
I have updated now, I had rebase errors so I had to restart my changes but all should be working now, please review |
|
Changes looks great! Well done! |
Book Library Pull Request
Self checklist
Changelist
Refactored code to include debugging and pass requirements.
Questions
No questions for reviewer.