Handle optional API data in pages

This commit is contained in:
lucast committed 2026-10-06 02:46:01 +02:00
1 parent a6485e5c73
commit 379acf400c
7 files changed
+23 -20

No files matched your search

+3 -3
View File
@@ -32,7 +32,7 @@ import { type Option } from "~/ui/SearchSelect.vue"
const { data: artistData } = useApiFetch<Artist[]>("/all/artists") const { data: artistData } = useApiFetch<Artist[]>("/all/artists")
const artistFetchOptions = async (q?: string): Promise<Option[]> => { const artistFetchOptions = async (q?: string): Promise<Option[]> => {
return artistData.value.map<Option>((g) => ({ return (artistData.value ?? []).map<Option>((g) => ({
label: g.name, label: g.name,
value: g._id, value: g._id,
})) }))
@@ -40,7 +40,7 @@ const artistFetchOptions = async (q?: string): Promise<Option[]> => {
const { data: genreData } = useApiFetch<Genre[]>("/all/genres") const { data: genreData } = useApiFetch<Genre[]>("/all/genres")
const genreFetchOptions = async (q?: string): Promise<Option[]> => { const genreFetchOptions = async (q?: string): Promise<Option[]> => {
return genreData.value.map<Option>((g) => ({ return (genreData.value ?? []).map<Option>((g) => ({
label: g.name, label: g.name,
value: g._id, value: g._id,
})) }))
@@ -113,7 +113,7 @@ const show = (id?: string) => {
return return
} }
const curItem: any = data.value.filter((i) => i._id == id)[0] const curItem: any = (data.value ?? []).filter((i) => i._id == id)[0]
if (!curItem) return if (!curItem) return
+1 -1
View File
@@ -79,7 +79,7 @@ const show = (id?: string) => {
return return
} }
const curItem: any = data.value.filter((i) => i._id == id)[0] const curItem: any = (data.value ?? []).filter((i) => i._id == id)[0]
if (!curItem) return if (!curItem) return
+1 -1
View File
@@ -71,7 +71,7 @@ const show = (id?: string) => {
return return
} }
const curItem: any = data.value.filter((i) => i._id == id)[0] const curItem: any = (data.value ?? []).filter((i) => i._id == id)[0]
if (!curItem) return if (!curItem) return
+4 -4
View File
@@ -32,7 +32,7 @@ import { type Option } from "~/ui/SearchSelect.vue"
const { data: artistData } = useApiFetch<Artist[]>("/all/artists") const { data: artistData } = useApiFetch<Artist[]>("/all/artists")
const artistFetchOptions = async (q?: string): Promise<Option[]> => { const artistFetchOptions = async (q?: string): Promise<Option[]> => {
return artistData.value.map<Option>((g) => ({ return (artistData.value ?? []).map<Option>((g) => ({
label: g.name, label: g.name,
value: g._id, value: g._id,
})) }))
@@ -40,7 +40,7 @@ const artistFetchOptions = async (q?: string): Promise<Option[]> => {
const { data: albumData } = useApiFetch<Album[]>("/all/albums") const { data: albumData } = useApiFetch<Album[]>("/all/albums")
const albumFetchOptions = async (q?: string): Promise<Option[]> => { const albumFetchOptions = async (q?: string): Promise<Option[]> => {
return albumData.value.map<Option>((g) => ({ return (albumData.value ?? []).map<Option>((g) => ({
label: g.name, label: g.name,
value: g._id, value: g._id,
})) }))
@@ -48,7 +48,7 @@ const albumFetchOptions = async (q?: string): Promise<Option[]> => {
const { data: genreData } = useApiFetch<Genre[]>("/all/genres") const { data: genreData } = useApiFetch<Genre[]>("/all/genres")
const genreFetchOptions = async (): Promise<Option[]> => { const genreFetchOptions = async (): Promise<Option[]> => {
return genreData.value.map<Option>((genre) => ({ return (genreData.value ?? []).map<Option>((genre) => ({
label: genre.name, label: genre.name,
value: genre._id, value: genre._id,
})) }))
@@ -201,7 +201,7 @@ const show = (id?: string) => {
return return
} }
const curItem: any = data.value.filter((i) => i._id == id)[0] const curItem: any = (data.value ?? []).filter((i) => i._id == id)[0]
if (!curItem) return if (!curItem) return
+5 -4
View File
@@ -9,6 +9,7 @@ const { data: albumData } = await useApiFetch<Album>(`/albums/${id.value}`)
const { data: tracksData } = await useApiFetch<Track[]>( const { data: tracksData } = await useApiFetch<Track[]>(
`/albums/${id.value}/tracks`, `/albums/${id.value}/tracks`,
) )
const tracks = computed(() => tracksData.value ?? [])
const { playAlbum, playShuffledAlbum, playAlbumAtIndex } = usePlayer() const { playAlbum, playShuffledAlbum, playAlbumAtIndex } = usePlayer()
useHead({ title: computed(() => albumData.value ? `${albumData.value.name} - Album` : "Album") }) useHead({ title: computed(() => albumData.value ? `${albumData.value.name} - Album` : "Album") })
@@ -30,12 +31,12 @@ useHead({ title: computed(() => albumData.value ? `${albumData.value.name} - Alb
<div class="buttons"> <div class="buttons">
<Button <Button
icon-name="lucide:play" icon-name="lucide:play"
@click="() => playAlbum(tracksData)" @click="() => playAlbum(tracks)"
>Play</Button >Play</Button
> >
<Button <Button
icon-name="lucide:shuffle" icon-name="lucide:shuffle"
@click="() => playShuffledAlbum(tracksData)" @click="() => playShuffledAlbum(tracks)"
>Shuffle</Button >Shuffle</Button
> >
</div> </div>
@@ -44,11 +45,11 @@ useHead({ title: computed(() => albumData.value ? `${albumData.value.name} - Alb
<section class="tracks"> <section class="tracks">
<TrackRow <TrackRow
v-for="(track, i) in tracksData" v-for="(track, i) in tracks"
:key="track._id" :key="track._id"
:track="track" :track="track"
:index="i" :index="i"
@play-album-at-index="() => playAlbumAtIndex(tracksData, i)" @play-album-at-index="() => playAlbumAtIndex(tracks, i)"
/> />
</section> </section>
</template> </template>
+6 -5
View File
@@ -13,13 +13,14 @@ const { data: albumsData } = await useApiFetch<Album[]>(
const { data: tracksData } = await useApiFetch<Track[]>( const { data: tracksData } = await useApiFetch<Track[]>(
`/artists/${id.value}/tracks`, `/artists/${id.value}/tracks`,
) )
const tracks = computed(() => tracksData.value ?? [])
const chunkedTracks = computed(() => { const chunkedTracks = computed(() => {
const SIZE = 3 const SIZE = 3
const chunks = [] const chunks = []
for (let i = 0; i < tracksData.value.length; i += SIZE) { for (let i = 0; i < tracks.value.length; i += SIZE) {
chunks.push(tracksData.value.slice(i, i + SIZE)) chunks.push(tracks.value.slice(i, i + SIZE))
} }
return chunks return chunks
@@ -56,12 +57,12 @@ useHead({ title: computed(() => artistData.value ? `${artistData.value.name} - A
<div class="buttons"> <div class="buttons">
<Button <Button
icon-name="lucide:play" icon-name="lucide:play"
@click="() => playAlbum(tracksData)" @click="() => playAlbum(tracks)"
>Play</Button >Play</Button
> >
<Button <Button
icon-name="lucide:shuffle" icon-name="lucide:shuffle"
@click="() => playShuffledAlbum(tracksData)" @click="() => playShuffledAlbum(tracks)"
>Shuffle</Button >Shuffle</Button
> >
</div> </div>
@@ -82,7 +83,7 @@ useHead({ title: computed(() => artistData.value ? `${artistData.value.name} - A
:track="track" :track="track"
:index="i + pI * 3" :index="i + pI * 3"
@play-album-at-index=" @play-album-at-index="
() => playAlbumAtIndex(tracksData, i + pI * 3) () => playAlbumAtIndex(tracks, i + pI * 3)
" "
/> />
</section> </section>
+3 -2
View File
@@ -5,6 +5,7 @@ const id = computed(() => route.params.id)
const { data: tracksData } = await useApiFetch<Track[]>( const { data: tracksData } = await useApiFetch<Track[]>(
`/artists/${id.value}/tracks`, `/artists/${id.value}/tracks`,
) )
const tracks = computed(() => tracksData.value ?? [])
const { playAlbumAtIndex } = usePlayer() const { playAlbumAtIndex } = usePlayer()
useHead({ title: "Artist Songs" }) useHead({ title: "Artist Songs" })
@@ -15,12 +16,12 @@ useHead({ title: "Artist Songs" })
<h1 class="title">Songs</h1> <h1 class="title">Songs</h1>
<TrackRow <TrackRow
v-for="(track, i) in tracksData" v-for="(track, i) in tracks"
:key="track._id" :key="track._id"
:track="track" :track="track"
:index="i" :index="i"
show-image show-image
@play-album-at-index="() => playAlbumAtIndex(tracksData, i)" @play-album-at-index="() => playAlbumAtIndex(tracks, i)"
/> />
</section> </section>
</template> </template>