Reputation: 293
I'm running into an issue trying to delete an item from a store. I have a route /view/:id
and am using that id to access a value from a custom writable store (items
). I wrote a simple selector method to retrieve the item data based on the id, and have created a reactive $: item
variable to listen for changes (items can be edited in this view). Here are the details from my <script>
// ItemView.svelte
export let params: { id?: string } = {};
import { push } from "svelte-spa-router";
import { items } from "./stores/items";
$: [item] = items.select($items, params.id);
function handleDelete() {
if (confirm("Are you sure you want to delete this item?")) {
items.delete(item.id);
push("/");
}
}
When I call handleDelete
, I get the following error:
Uncaught (in promise) TypeError: can't access property "type", ctx[0] is undefined
update bundle.js:3796
update index.mjs:764
flush index.mjs:732
promise callback*schedule_update index.mjs:707
make_dirty index.mjs:1442
ctx index.mjs:1477
7 bundle.js:3898
set index.mjs:35
update index.mjs:43
delete items.ts:59
handleDelete ItemView.svelte:17
If I wrap items.delete(item.id)
in a timeout, then everything works (5ms did the trick), but that doesn't seem right. I don't have a lot of experience with Svelte, but it feels like the issue is with the reactive variable unsubscribing. Should I be getting the single item data differently? Do I need to manually unsubscribe from the store before navigating?
I tried calling unsubscribe
manually, but that didn't work either:
export let params: { id?: string } = {};
import { push } from "svelte-spa-router";
import { items } from "./stores/items";
import { onDestroy } from "svelte";
let item;
const unsubscribe = items.subscribe(
(value) => (item = items.select(value, params.id)[0])
);
function handleDelete() {
if (confirm("Are you sure you want to delete this item?")) {
unsubscribe(); // <- Here
items.delete(item.id);
push("/");
}
}
onDestroy(unsubscribe);
That gave me the following error:
Uncaught (in promise) TypeError: stop is not a function
subscribe index.mjs:58
run index.mjs:18
run_all index.mjs:24
destroy_component index.mjs:1431
update bundle.js:918
I'm not committed to any of the code I posted; I just want to be able to view a single item, and delete it and navigate away.
Upvotes: 1
Views: 1693
Reputation: 293
I learned that ctx
in the error message referred to the right-hand side of the reactive variable assignment. In this instance, that was the return from my select method: items.select($items, params.id)
.
ctx[0]
is the first item in that array, or the variable that I created by destructuring: $: [item]
.
So when Svelte said ctx[0] is undefined
, it meant that there was no first entry in the ctx
array; item
was undefined (because it had been deleted).
I thought there was something important about the property "type", but it ended up just being the first key on item
that I was trying to access in my markup: {item.type}
. Trying to access any property would have failed.
By wrapping everything in an {#if item}
condition, I was able to resolve the error:
<!-- ItemView.svelte -->
{# if item}
<p>Type: {item.type}</p>
{/if}
I wouldn't recommend any of the above as a good pattern to follow. But if you are looking to resolve a similar issue, consider this solution.
Upvotes: 2