Skip to content

Improve access token handling#8

Draft
aaronskiba wants to merge 12 commits intodevelopmentfrom
improve-access-token-handling
Draft

Improve access token handling#8
aaronskiba wants to merge 12 commits intodevelopmentfrom
improve-access-token-handling

Conversation

@aaronskiba
Copy link
Owner

@aaronskiba aaronskiba commented Mar 7, 2026

Overview

This PR adds access token refresh logic to AuthContext.useFetch, a newly added custom hook, has been created to centralize async data fetching from Spotify. The access token handling logic has been integrated with useFetch.

Other features (Loader and ErrorMessage components) have been added. Several bugfixes (useAuth() destructuring and null-safe handling for playlist.images) are included, and much refactoring has been performed as well.

With the exception of `SpotifyPlaylistActions`, moved all prop type definitions from `src/types/SpotifyPlaylistProps.ts` to the components that actually use them.
It is possible for `playlist.images == null`. This change adds null-safe handling whenever attempting to access `playlist.images[0].url`.
This refactor centralizes and generalizes async data fetching, reducing duplication and simplifying component logic.

Create custom `useFetch` hook (`src/hooks/useFetch.ts`)
- Move data-fetching logic from components into reusable hook
- Remove local useEffect-based fetch implementations from:
  - `src/components/CompareTracks.tsx`
  - `src/components/Playlists.tsx`
  - `src/components/PlaylistTracks.tsx`
- Remove component-level useState related to fetching

TODO / Follow-up work:
- Add error handling support
- Add isLoading state handling
- Introduce request cancellation via AbortController
Add AbortController and cleanup logic to useFetch
- Pass AbortSignal to fetchFn and underlying fetch calls

Update components using useFetch to receive `AbortSignal`

Update services to accept optional `signal?: AbortSignal`:
- playlistService.ts
- spotifyApi.ts
- trackService.ts
- Refactor `useFetch` to return `data = null` unless a request completes successfully

- Introduce `ErrorMessage` component for rendering Spotify API errors

- Update `useFetch` consumers to explicitly handle loading, error, and data states

- Render `<ErrorMessage />` when error is present

- Render data components only when data is non-null
Add src/hooks/useFetchSpotify.ts

Add useFetchPlaylists and useFetchTracks custom hooks

Composes Spotify service calls with generic useFetch

Removes fetch wiring logic from UI components
- Within `useFetch`, add `isLoading` to `fetchState`.
- Add Loader component
- Use Loader component within components that rely on `useFetch`
Update `AuthContext`
- Provide `accessToken` (string|null), rather than full `auth` object
  - `isAuthenticated` boolean is now based off of `accessToken` presence
  - Update corresponding components (`Playlists`, `PlaylistTracks`, `CompareTracks`) to now read `accessToken`
  - Update `useFetchPlaylists` and `useFetchTracks` to handle null `accessToken`
- Add a small token expiry buffer and `isExpiredToken` helper
- Add `setAuth(null)` within login error.
@aaronskiba aaronskiba force-pushed the improve-access-token-handling branch 2 times, most recently from 3d60262 to 5924a5e Compare March 9, 2026 02:19
Add token refresh logic to AuthContext, and integrate valid access token handling with useFetch. This change allows us to stop passing access tokens throughout the app

Key changes:
- `AuthContext` now exposes `getValidAccessToken()` which auto-refreshes expired tokens, updates context state, and prevents concurrent refreshes via a ref.
- Added `src/utils/authToken.ts` with `isValidToken`, `getAccessTokenExpirationDate`, and `getUpdatedAuthFromRefreshResponse` helpers.
- Added `getRefreshToken()` in `src/services/authService.ts` to call Spotify's token endpoint and added `SpotifyRefreshResponse` type (`src/types/SpotifyAuth.ts`).
- `useFetch` now retrieves a valid access token via `useAuth` and passes it to fetch functions; `fetchFn` signature changed to `(accessToken, signal)`.
  - Updated `useFetchSpotify` hooks (`useFetchPlaylists`, `useFetchTracks`) and components (Playlists, PlaylistTracks, CompareTracks) to correspond with these changes

This change centralizes token handling, prevents duplicate refresh requests, and simplifies component usage.
@aaronskiba aaronskiba force-pushed the improve-access-token-handling branch from 5924a5e to cbae38c Compare March 15, 2026 02:48
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.

1 participant