I'm using Svelte for the first time, and I'm trying to figure out how to apply filtering to a list retrieved from an API. My EventsIndex component is very simple, and comprises the following logic:
import FetchPosts from '../services/postsByType'
import EventCard from '../components/EventCard.svelte'
export let post_type
let events = new FetchPosts( post_type ).get()
let currentCategory = 0
function updateCategory( catId ) {
currentCategory = catId
}
Everything works just as expected.
I'm also using the await template syntax to display the relevant data:
{#await events}
<h1>loading...</h1>
{:then events}
<section >
{#each events as event}
<EventCard event={event} on:filter={updateCategory}/>
{/each}
</section>
{:catch error}
<p>Something went wrong...</p>
{/await}
The missing piece is the reactive filtered list. I thought I could do the following, but it generates the error events.map is not a function
, which makes sense, as the events variable would be an unresolved promise when filteredEvents is invoked.
$: filteredEvents = () => {
if (currentCategory === 0) return events
return events.filter( event => {
return event.categories !== null
? event.categories.some( cat => cat.id == currentCategory )
: false
})
}
So how would I add a reactive filteredEvents function, that I can also include in my template?
CodePudding user response:
Filtering on the events inside the {#each}
loop should work. If the filter function was very short like this I'd apply it inline
{#each events.filter(e => e.id === currentId) as event}
Just as an example. Since in your case the filter function is more complex, moving it to a function might be the better option
filterEvents(events, currentCategory) {
if (currentCategory === 0) return events
return events.filter( event => {
return event.categories !== null
? event.categories.some( cat => cat.id == currentCategory )
: false
})
}
</script>
...
{#each filterEvents(events, currentCategory) as event}
(I think you can replace this
return event.categories !== null
? event.categories.some( cat => cat.id == currentCategory )
: false
by this
event?.categories.some( cat => cat.id === currentCategory )