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

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:

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 and extends)

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