Reputation: 530
I'm using svelte-pathfinder to observe URL parameters that are then sent to a method which runs an async API call. I'd like to be able to re-run my API call based on the current path at an interval (for example, every 50 seconds).
stores.js (note that fetchContests
is a method that runs a await fetch()
call to an external API based on the pattern
and query
values from svelte-pathfinder
:
// routing
export const resultStore = derived([pattern, query], ([$pattern, $query], set) => {
if ($pattern('/search/') && $query.params.q) {
new Promise((resolve) => {
setTimeout(() => {
fetchContests('title', $query.params.q, true)
.then(set);
resolve()
}, delay)
})
} else if ($pattern('/')) {
new Promise((resolve) => {
setTimeout(() => {
fetchContests('contest_ids', dashboard, true)
.then(set);
resolve({name: "testing"})
}, delay)
})
}
}, []);
Results.svelte (where I display the results of the API call):
<script>
// data
export let promise;
import { resultStore } from './../stores.js';
// layout components
import Contest from "./Contest.svelte";
</script>
{#await promise}
<p>Loading contests</p>
{:then}
<ul>
{#each $resultStore as contest}
<Contest contest="{contest}"/>
{/each}
</ul>
{:catch error}
<p>Something went wrong: {error.message}</p>
{/await}
This works really well in a non-repetitive way:
What I haven't been able to do is add setInterval
to this in a way that preserves the path. So if the path is http://localhost:8080/#!/search?q=governor
and 50 seconds have elapsed, the interval would make an API call with those current parameters to retrieve updated data. If the path is http://localhost:8080/
, or http://localhost:8080/#!/search?q=senator
instead when the next 50 seconds have elapsed, it would do the same with those parameters.
Originally, I thought maybe I could add setInterval
to the API call itself, which is an async function
that runs await fetch
. But this didn't work, it would run multiple API calls ignoring the current path and parameter settings. I thought maybe I could run it within resultStore
instead (above), but then it only ran after 50 seconds instead of running on initial page load and then again after each 50 second interval.
Upvotes: 0
Views: 452
Reputation: 7721
When extracting the logic that should run every time pattern
or query
changes and after a given interval after that, I think this might match what you want to do?
let delay = 50000
// routing
export const resultStore = derived([pattern, query], ([$pattern, $query], set) => {
fetchAndSet($pattern, $query, set)
const interval = setInterval(() => {
fetchAndSet($pattern, $query, set)
}, delay);
// If you return a function from the callback, it will be called when
// a) the callback runs again, or b) the last subscriber unsubscribes.
return () => {
clearInterval(interval);
};
}, []);
function fetchAndSet($pattern, $query, set) {
if ($pattern('/search/') && $query.params.q) {
fetchContests('title', $query.params.q, true).then(set)
} else if ($pattern('/')) {
fetchContests('contest_ids', dashboard, true).then(set)
}
}
Upvotes: 1