Skip to content

Commit

Permalink
Resolve one of the hanging issues
Browse files Browse the repository at this point in the history
There appear to be multiple issues.  I resolved one of them which was
caused by a typo.  There appear to be two issues remaining:

-   Sometimes, the server returns a 401.  This could be a rate limit or
    an expired token?

-   The application still hangs but it happens after expanding a few
    more 'ArtistTree' components.
  • Loading branch information
asynts committed Oct 2, 2022
1 parent 97ada6b commit aac76f5
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 28 deletions.
68 changes: 68 additions & 0 deletions docs/issues/0002_infinite-nested-object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
70f24deba8c25f3dbb107b88ef957d753887781f

It appears as if the `action.payload` object has been corrupted somehow.

### Notes

- This is what it looks like in the console if I print it out:

```none
[
{
"id": "4RddZ3iHvSpGV4dvATac9X",
"expand": false,
"name": "Papa Roach",
"relatedArtistIds": null,
"4RddZ3iHvSpGV4dvATac9X": {
"id": "4RddZ3iHvSpGV4dvATac9X",
"expand": false,
"name": "Papa Roach",
"relatedArtistIds": null,
"4RddZ3iHvSpGV4dvATac9X": {
"id": "4RddZ3iHvSpGV4dvATac9X",
"expand": false,
"name": "Papa Roach",
"relatedArtistIds": null,
"4RddZ3iHvSpGV4dvATac9X": /* ... */
}
}
}
];
```
- I tried converting the object to JSON to be able to put it here but I get this error:
```none
TypeError: Converting circular structure to JSON
```
- The first thing that I notice is, that it can't create display the related artists.
They appear in the `relatedArtistIds` of the `rootArtist` but they are not saved in `state.artists`.
- I noticed that the `newArtists` that we compute in `LOAD_ARTISTS_IF_NOT_EXIST` is empty.
### Ideas
- Look for `{ [id]: "foo" }` in the codebase, that is where things could go wrong.
- I suspect, that this is a nasty typo.
### Solution
- It was a typo:
```js
let newArtists = {};
for (let newArtist of action.payload) {
newArtist[newArtist.id] = newArtist;
}
```
should be:
```js
let newArtists = {};
for (let newArtist of action.payload) {
newArtists[newArtist.id] = newArtist;
}
```
35 changes: 19 additions & 16 deletions src/providers/ArtistProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,45 @@ function ASSERT_NOT_REACHED() {
Artist {
id: int
name: string
expand: boolean
relatedArtistIds: list[int]?
}
*/

let initialValue = {
artists: {
"6XyY86QOPPrYVGvF9ch6wz": { id: "6XyY86QOPPrYVGvF9ch6wz", name: "Linkin Park", relatedArtistIds: null },
"6XyY86QOPPrYVGvF9ch6wz": {
id: "6XyY86QOPPrYVGvF9ch6wz",
name: "Linkin Park",
relatedArtistIds: null,
expand: false,
},
},
rootArtistId: "6XyY86QOPPrYVGvF9ch6wz",
};

let actions = {
SET_EXPAND: "SET_EXPAND",
SET_RELATED_ARTIST_IDS: "SET_RELATED_ARTIST_IDS",
ADD_ARTIST_IF_NOT_EXISTS: "ADD_ARTIST_IF_NOT_EXISTS",
LOAD_ARTISTS_IF_NOT_EXIST: "LOAD_ARTISTS_IF_NOT_EXIST",
};

function reducer(state, action) {
switch (action.type) {
case actions.ADD_ARTIST_IF_NOT_EXISTS:
// Return early if artist already exists.
if (state.artists[action.payload.id] !== undefined) {
return state;
case actions.LOAD_ARTISTS_IF_NOT_EXIST:
let newArtists = {};
for (let newArtist of action.payload) {
newArtists[newArtist.id] = newArtist;
}

return {
...state,
artists: {
// First take the new values, then override with existing values.
// Thus we keep all the related artist that have been loaded already.
...newArtists,
...state.artists,
[action.payload.id]: action.payload.value,
},
};
case actions.SET_EXPAND:
Expand Down Expand Up @@ -88,15 +96,10 @@ export function ArtistProvider(props) {

let relatedArtists = await server.fetchRelatedArtistsAsync(artist.id);

for (let relatedArtist of relatedArtists) {
dispatch({
type: actions.ADD_ARTIST_IF_NOT_EXISTS,
payload: {
id: relatedArtist.id,
value: relatedArtist,
},
});
}
dispatch({
type: actions.LOAD_ARTISTS_IF_NOT_EXIST,
payload: relatedArtists,
});

// This is safe, even if the request was made multiple times.
dispatch({
Expand Down
5 changes: 0 additions & 5 deletions src/providers/AuthProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,10 @@ export function AuthEndpoint(props) {
return;
}

console.log(window.location.href);

// Extract the access token from the URL fragment.
// There are some technical reasons why this is being passed in the fragment and not in the query.
let urlSearchParameters = new URLSearchParams(window.location.hash.substring(1));

console.log(urlSearchParameters.get("state"), urlSearchParameters.get("access_token"));
console.log(localStorage.getItem("spotify-oauth-state"))

ASSERT(urlSearchParameters.get("state") === localStorage.getItem("spotify-oauth-state"));
localStorage.setItem("spotify-oauth-token", urlSearchParameters.get("access_token"));

Expand Down
13 changes: 6 additions & 7 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,10 @@ export async function fetchRelatedArtistsAsync(artist_id) {

let json = await spotifyApiGET(`/artists/${artist_id}/related-artists`);

return json.artists.map(artist => {
return {
id: artist.id,
name: artist.name,
relatedArtistIds: null,
};
});
return json.artists.map(artist => ({
id: artist.id,
name: artist.name,
relatedArtistIds: null,
expand: false,
}));
}

0 comments on commit aac76f5

Please sign in to comment.