-
Notifications
You must be signed in to change notification settings - Fork 1
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
Frontend api #12
Conversation
…om backend since it was a breaking change
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.
Good start, I have two requests:
- 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 - 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:
- Add a file
src/api/requests.ts
containing exported functionsget
,post
, andput
which call a non-exported functionfetchRequest
. The latter wraps afetch
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 repeatedmethod: "..."
orheaders: { "Content-Type": "..." }
. - Rename
src/api/task_api.ts
tosrc/api/tasks.ts
(to avoid redundancy). Move theTask
interface definition to this file as an export. Rename theTaskInput
interface toCreateTaskRequest
and remove theisChecked
field (for updating a task, we can just use the fullTask
type as the input). RefactorcreateTask()
to use the new request functions. - Remove
src/models/task.ts
.
- Add a file
frontend/package.json
Outdated
@@ -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", |
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.
Is this package being used? If not then let's remove it
frontend/src/api/task_api.ts
Outdated
// 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. |
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.
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."
frontend/src/api/task_api.ts
Outdated
// true if HTTP code is between 200 and 300 | ||
if (response.ok) { |
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.
// 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) { |
frontend/src/api/task_api.ts
Outdated
* @param init the necessary initialization parameters | ||
* @returns the fetch response or throws an error | ||
*/ | ||
async function fetchData(input: RequestInfo, init?: RequestInit) { |
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 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
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.
yeah that makes sense, i've refactored to the fulcrum approach. def a lot cleaner
frontend/src/api/task_api.ts
Outdated
|
||
console.log(response); | ||
|
||
return await response.json(); |
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.
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.
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.
interesting, i didn't know that, addressed
frontend/src/api/task_api.ts
Outdated
body: JSON.stringify(task), | ||
}); | ||
|
||
console.log(response); |
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.
Remove console log
frontend/src/models/task.ts
Outdated
* 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; |
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.
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.
Changes
What changes did you make? Include screenshots if applicable, or explain how to view the changes.
Testing
How did you confirm your changes work? (Automated tests, manual verification, etc.)
Tracking
Add your issue number below.
Resolves #10