Skip to content
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

Frontend api #12

Closed
wants to merge 20 commits into from
Closed

Frontend api #12

wants to merge 20 commits into from

Conversation

navidboloorian
Copy link
Contributor

Changes

What changes did you make? Include screenshots if applicable, or explain how to view the changes.

  • Created fetch calls to createTask and the function outline for getAllTasks

Testing

How did you confirm your changes work? (Automated tests, manual verification, etc.)

  • made calls from the frontend and verified that new tasks were being created in the database

Tracking

Add your issue number below.

Resolves #10

@navidboloorian navidboloorian requested a review from wllmwu as a code owner August 15, 2023 05:56
Copy link
Member

@wllmwu wllmwu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start, I have two requests:

  1. Can you rebase this branch onto main to remove the commits from the update-backend branch (Update backend #9) and make sure you have the latest frontend files? I think a basic rebase might work but if not, try stashing the changes from the unmerged commits, checking out a new branch from main, popping the changes off the stash, and making a new PR. This is so we can see what's actually changed in this branch
  2. I think we can take an easier, more modular approach to the API client. Right now it's not clear to me how one would extend this to incorporate User and other objects without still repeating a lot of code. But Fulcrum's API client implementation seems pretty solid and I think we should use that as our model. Here are my suggestions:
    1. Add a file src/api/requests.ts containing exported functions get, post, and put which call a non-exported function fetchRequest. The latter wraps a fetch call. The exported functions are also just wrappers that plug in the specific HTTP method and check the response code + throw if not ok, analogous to the functions of the same name in that Fulcrum file. The idea here is that when we write a new API client function, we should only need to write a URL and a body if applicable, no repeated method: "..." or headers: { "Content-Type": "..." }.
    2. Rename src/api/task_api.ts to src/api/tasks.ts (to avoid redundancy). Move the Task interface definition to this file as an export. Rename the TaskInput interface to CreateTaskRequest and remove the isChecked field (for updating a task, we can just use the full Task type as the input). Refactor createTask() to use the new request functions.
    3. Remove src/models/task.ts.

@@ -12,6 +13,7 @@
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@types/react-helmet": "^6.1.6",
"http-proxy-middleware": "^2.0.6",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this package being used? If not then let's remove it

Comment on lines 3 to 9
// a customized fetch wrapper that handles errors
// wrapping fetch in a try-catch does not handle errors as expected so a custom
// wrapper is necessary

/**
* A customized fetch wrapper that handles errors. Wrapping fetch in a try-catch
* does not handle errors as expected so a custom wrapper is necessary.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove duplicate comment. Also suggest rewording to be more specific about what "handle errors as expected" means because a new developer probably has no expectations regarding this. Maybe something like "The fetch function only throws an error in special cases such as network issues, so we still have to handle actual error responses ourselves."

Comment on lines 18 to 19
// true if HTTP code is between 200 and 300
if (response.ok) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// true if HTTP code is between 200 and 300
if (response.ok) {
// true if status code indicates success (200-299) or redirect (300-399), false otherwise
if (response.ok) {

* @param init the necessary initialization parameters
* @returns the fetch response or throws an error
*/
async function fetchData(input: RequestInfo, init?: RequestInit) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way this is written, we'd need a fetchData function in every XX_api.ts file. I'll suggest a revised approach in the top level review comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah that makes sense, i've refactored to the fulcrum approach. def a lot cleaner


console.log(response);

return await response.json();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the return type of json() is Promise<any> which basically disables type checks. (That's why there are no type errors here even though you've specified that createTask() returns Promise<Task> without doing anything to ensure that's the case.) I'd just change this to return await response.json() as Task to be safe and consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, i didn't know that, addressed

body: JSON.stringify(task),
});

console.log(response);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove console log

Comment on lines 2 to 12
* Initializes the shape for the data being retrieved from the backend.
*/
export interface Task {
_id: string;
title: string;
description?: string;
isChecked: boolean;

// data received will be in JSON, JSON does not have a date type so we use
// a string instead
dateCreated: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what "initializes" means here, this is just defining a type. I think we should solidify what the intended use of this type is though, in case it wasn't clear--this is what all the rest of the frontend should see when components use a Task object, not necessarily what our API client functions actually receive in an HTTP response. To that end, I'd change dateCreated back to a Date object and add the conversion logic in the API client. Since there will be multiple functions that return a Task, it probably makes sense to write some kind of parseTask() function which turns the output of response.json() into a Task object that frontend components can use, or throws an error if something doesn't match what's expected.

@navidboloorian navidboloorian requested a review from wllmwu August 19, 2023 08:09
@wllmwu wllmwu deleted the frontend-api branch August 22, 2023 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Write frontend API client
2 participants