Issue Recap
During the project, I have tried to keep issues to track work and progress.
Online Issues: 120 commits since October
Extra Credit N@TM Extra Credit
- Contributions My analytics page on Github
- Spacebook API Functions Where we set plans for all our functions, in tandem with DrawIO
- Spacebook API 500 Error I got 500 errors a lot in our project, so I had to keep trying to fix them and learned a lot about debugging in the process.
- Leaderboard API CORS Error We got a CORS error in the functions often, so I had to help develop SecurityConfig to resolve this
- DrawIO Diagram Where we set plans for all our functions, in tandem with functions
Overview of Spacebook
Main Spacebook file:
public class Spacebook {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private byte[] image;
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
@Column
private int like;
@Column
private int dislike; // track the number of dislikes
public int getLike() {
return like;
}
public void setLike(int like) {
this.like = like;
}
public int getDislike() {
return dislike;
}
public void setDislike(int dislike) {
this.dislike = dislike;
}
public String toString() {
return "Product [id=" + id + ", image=" + image + "]";
}
}
Defines likes, dislikes, id, and the image variable as a byte array
ApiController for liking:
@PostMapping("/like/{fileName}")
public ResponseEntity<Spacebook> setUpVote(@PathVariable String fileName) {
Optional<Spacebook> optional = uploadFileRepository.findByfileName(fileName);
if (optional.isPresent()) {
Spacebook spacebook = optional.get();
spacebook.setLike(spacebook.getLike()+1);
uploadFileRepository.save(spacebook);
return new ResponseEntity<>(spacebook, HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
ApiController for disliking:
@PostMapping("/dislike/{fileName}")
public ResponseEntity<Spacebook> setDownVote(@PathVariable String fileName) {
Optional<Spacebook> optional = uploadFileRepository.findByfileName(fileName);
if (optional.isPresent()) {
Spacebook spacebook = optional.get();
spacebook.setDislike(spacebook.getDislike()+1);
uploadFileRepository.save(spacebook);
return new ResponseEntity<>(spacebook, HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
Both are amended to alter by filename rather than id.
ApiController for deleting posts:
// It is marked as @Transactional to ensure that either all operations work or none do, GPT suggested.
@Transactional
@DeleteMapping("/delete/{fileName}")
public ResponseEntity<String> deleteSpacebook(@PathVariable String fileName) {
Optional<Spacebook> optional = uploadFileRepository.findByfileName(fileName);
if (optional.isPresent()) {
Spacebook spacebook = optional.get();
// Delete the Spacebook entry with the given file name from the repository.
uploadFileRepository.deleteByfileName(fileName);
// Return a success response indicating that the image has been deleted.
return new ResponseEntity<String>("Image has been deleted", HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
public interface SpacebookJpaRepository extends JpaRepository<Spacebook, Long> {
// Method to find a Spacebook object by its file name.
Optional<Spacebook> findByfileName(String fileName);
// Method to delete a Spacebook entry by its file name.
void deleteByfileName(String fileName);
}
I amended the method to deletebyfilename instead of byid to assist with project parity (the get function was based off filename). I also learned how to customize ResponseEntities as I ran into an error where I had to debug why the ResponseEntity couldn’t recognize my message (it turns it was in the format for an array not a String). The deletebyfileName method was a learning experience because I spent a long time trying to figure out where/how it was defined to run.
Scrapped Comment Function to be implemented for the Future
private List<String> comments = new ArrayList<>();
private static List<String> initComment() {
ArrayList<String> comments = new ArrayList<>();
comments.add("You suck");
return comments;
};
@PostMapping("/comment/{id}")
public ResponseEntity<Spacebook> setComment(@PathVariable String comment, @PathVariable long id) {
Optional<Spacebook> optional = repository.findById(id);
if (optional.isPresent()) {
Spacebook spacebook = optional.get();
// Get the current list of comments from the Spacebook object.
List<String> comments = spacebook.getComments();
// Add the new comment to the list of comments.
comments.add(comment);
// Set the updated list of comments in the Spacebook object.
spacebook.setComments(comments);
}
}
As I wrote this code, I learned how to initialize a comments list, handle HTTP requests to add comments to a specific Spacebook object, and ensure that the comments are associated with the correct Spacebook entry in the repository. Meant to upload comments to an associated spacebook, scrapped because we needed to focus on integration and narrow our scope on frontend implementation. We can still use this.
Old Upload Code
@PostMapping("/upload")
public ResponseEntity<String> saveSpacebookToDB(@RequestParam("file") String file) {
// Check if the "file" parameter is empty. If so, return a bad request response.
if (file.isEmpty()) {
return new ResponseEntity<>("Please select a file to upload.", HttpStatus.BAD_REQUEST);
}
try {
// Decode the Base64 encoded image data.
byte[] imageBytes = Base64.getDecoder().decode(file);
// Create a new Spacebook object and set the image data.
Spacebook spacebook = new Spacebook();
spacebook.setImage(imageBytes);
// Save the Spacebook object to the database.
Spacebook savedSpacebook = spacebookRepo.save(spacebook);
// Return a success response with the Spacebook ID.
return new ResponseEntity<>("Image uploaded successfully. Spacebook ID: " + savedSpacebook.getId(), HttpStatus.OK);
} catch (Exception e) {
// If an exception occurs during the process, print the stack trace and return an internal server error response.
e.printStackTrace();
return new ResponseEntity<>("Upload failed.", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
This threw a 500 error with the new Spring Portfolio, so we scrapped it before we realized it was the Spring Portfolio and remade it later. I used a try and catch method to help with debugging the 500 error.
Overview of Leaderboard
My idea to create a HashMap to store associated player names and scores. I felt like a HashMap would be more intuitive to use than a 2D array or related ArrayLists.
public static HashMap<String, Integer> init() {
HashMap<String, Integer> leaderboardHash = new HashMap<>();
{
leaderboardHash.put("Player1", 1000);
leaderboardHash.put("Player2", 800);
leaderboardHash.put("Player3", 1200);
leaderboardHash.put("Player4", 4000);
leaderboardHash.put("Player5", 670);
leaderboardHash.put("Player6", 320);
leaderboardHash.put("Player7", 570);
leaderboardHash.put("Player8", 129);
leaderboardHash.put("Player9", 250);
leaderboardHash.put("Player10", 875);
}
return leaderboardHash;
}
QuizLeaderboard
@PostMapping("/post/{leaders}/{score}")
public ResponseEntity<QuizLeaderboard> postQuizLeaderboard(@PathVariable String leaders, @PathVariable int score) {
// A person object WITHOUT ID will create a new record with default roles as student
QuizLeaderboard quizLeaderboard = new QuizLeaderboard(null, leaders, score);
repository.save(quizLeaderboard);
return new ResponseEntity<>(quizLeaderboard, HttpStatus.OK);
}
I helped Tay with changing the parameters for postQuizLeaderboard from @RequestMapping to @PathBariables
Frontend Side
<script>
document.getElementById("uploadForm").addEventListener("submit", function (event) {
event.preventDefault();
const form = new FormData(this);
// Create a new XMLHttpRequest object
const xhr = new XMLHttpRequest();
// Define the HTTP method and the URL
xhr.open("POST", "https://cosmic-backend.stu.nighthawkcodingsociety.com/image", true);
// Set CORS headers
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
// Handle the response
xhr.onload = function () {
if (xhr.status === 200) {
console.log("Image request successful!");
} else {
console.error("Image request failed with status: " + xhr.status);
}
};
// Send the request
xhr.send(form);
});
</script>
I assisted in frontend development for fetching spacebook from the frontend.
Key Commits:
- String to byte array This is where we decided to encode base64 strings
- Create basic frontend for future implementation This is where I worked on making a page for frontend for future Spacebook integration
Struggles
- 500 Error: When uploading using Spacebook, the new spring portfolio template threw an internal server error. I used the debug function in VSCode and helped revert to the old spring portfolio to resolve this.
- Understanding error codes and how to fix them (404, 400)
- Main.java Errors: Small compiler errors that don’t show up before running main were difficult to understand.
- Just familiarization with a new environment
Collegeboard Quiz Notes:
- Using scratch paper or help thought process
- Question 4: remember that int operations return ints not decimals
- Question 10: Recursive function, remember to look out for break errors
- Question 16: Use an example case to help figure out if it is +/- 1
- Question 18: Use Math.Random in personal code from now on for AP prep (I looked up the syntax)
- Question 19: Need to review boolean algebra, “not” “not” cancels them out
- Question 21: Be cautious on enhanced for loops, the first variable gets an element not an index
- Question 38: Boolean algebra, solve for each expression and check which is right
Plans to study for AP Exam:
- Doing extra practice MC and FRQ on Collegeboard
- As AP Exams get closer, ramp up practice
- Do full practice exams
- Review in class student teaching, discuss any problems
- Create programs and practical functions with topics unfamiliar:
- Especially: Recursion and Inheritance (
super
andextends
)
- Especially: Recursion and Inheritance (
Trimester 1 Reflections
What did I learn?
- Familiarize with Spring portfolio
- Inheritance and Boolean Algebra
- public vs private in Java
- AGILE Framework
- Benefits of planning
Positive Accomplishments
- I am much more familiar with backend/spring portfolio as well as Postman
- Spacebook likes, dislikes, upload assist
- Developed debugging knowledge (reading the error messages)
What can I improve on/Future plans?
- I want to learn more about boolean algebra and get better and faster at it
- I want to get in the habit of writing better and more frequent comments to aid in collaboration
- I want to get algorithms down (sorting/searching functions especially)
- Work on speed because AP exam will be timed