Skip to content

Commit

Permalink
Make "download data" contents not "[]"/"undefined" (#89)
Browse files Browse the repository at this point in the history
Currently the download link is randomly broken because when the `url.current` ref changes the `<a>` doesn't necessarily re-render. Using `setState` ensures that the `<a>` re-renders immediately when the data changes.

This currently causes the behavior where the download link gives you a file containing the initial state of `data` (`[]` on the comparisons page, `undefined` on the bar plots) rather than the most up-to-date contents of `data` (which should be populated once data is successfully fetched).
  • Loading branch information
sid-kap committed Mar 2, 2024
1 parent 5c2f824 commit 12912e9
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 32 deletions.
33 changes: 13 additions & 20 deletions lib/PlotsTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useRef } from "react"
import { useEffect, useState } from "react"

import BarPlot from "lib/BarPlot"
import { CurrentYearExtrapolationInfo } from "lib/projections"
Expand Down Expand Up @@ -83,11 +83,7 @@ export default function PlotsTemplate({
{selected?.has_ca_hcd_data && <HcdDataInfo />}
</div>
</div>
<DownloadData
data={data}
name={selected?.name + ".json"}
selected={selected?.name}
/>
<DownloadData data={data} name={selected?.name + ".json"} />
</div>
</div>
)
Expand All @@ -96,30 +92,27 @@ export default function PlotsTemplate({
export function DownloadData({
data,
name,
selected,
}: {
data: object
name: string
selected: any
}): JSX.Element {
const url = useRef("#")
const [url, setUrl] = useState("#")

// This runs every time selected changes
// This runs every time data changes
useEffect(() => {
url.current = URL.createObjectURL(
new Blob([JSON.stringify(data)], { type: "octet/stream" })
)
// Cleanup function
return () => {
if (url.current != "#" && typeof window !== "undefined") {
URL.revokeObjectURL(url.current)
}
if (url != "#") {
URL.revokeObjectURL(url)
}
}, [selected])
setUrl(
URL.createObjectURL(
new Blob([JSON.stringify(data)], { type: "application/json" })
)
)
}, [data])

Check warning on line 111 in lib/PlotsTemplate.tsx

View workflow job for this annotation

GitHub Actions / Lint Code Base

React Hook useEffect has a missing dependency: 'url'. Either include it or remove the dependency array

return (
<a
href={url.current}
href={url}
className="text-sm text-blue-500 hover:text-blue-300"
download={name}
>
Expand Down
18 changes: 11 additions & 7 deletions lib/queries.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { useQuery } from "react-query"

export function useFetch(url) {
return useQuery(
url,
/* eslint-disable */
() => fetch(url).then((res) => res.json()),
/* eslint-enable */
{ staleTime: Infinity }
)
return useQuery({
queryKey: url,
queryFn: () => {
if (url) {
return fetch(url).then((res) => res.json())
} else {
return []
}
},
staleTime: Infinity,
})
}
6 changes: 1 addition & 5 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -496,11 +496,7 @@ export default function Home(): JSX.Element {
{perCapitaInput}
{groupingInput}
{selectedLocations.some((l) => l.has_ca_hcd_data) && preferHcdDataInput}
<DownloadData
data={data}
name="housing data comparisons.json"
selected={selectedLocations}
/>
<DownloadData data={data} name="housing data comparisons.json" />
{selectedLocations.some((l) => l.has_ca_hcd_data) && <HcdDataInfo />}
</div>
</Page>
Expand Down

0 comments on commit 12912e9

Please sign in to comment.