Trying to convert a simple tutorial that was using localStorage to instead use IndexedDB, but having trouble with reactivity. The list of movies don't update until i do a page refresh. Anyone who can point me in the right dirction? Thanks!
Below code updated with some changes suggested by Thomas Hennes in one of the answers, thanks! Still having problem with needing a manual page refresh though. Also added MovieList.svelte
App.svelte
<script>
import MovieInput from "./MovieInput.svelte";
import MovieList from "./MovieList.svelte";
import Search from "./Search.svelte";
import db from "./db.js";
import Dexie from "dexie";
//get a promise containing all movies in IndexedDB (if collection exists)
let movies = db.movies.count(function (value) {
return (movies = value > 0 ? db.movies.toArray() : []);
});
//add new item to IndexedDb
const submitMovie = (movie) => {
db.movies.put({ title: movie.title, rating: movie.rating });
};
</script>
<div class="main">
<h1>Movie Journal</h1>
<MovieInput on:submitMovie={(event) => submitMovie(event.detail.movie)} />
{#await movies}
<div>Loading movies...</div>
{:then movieArray}
<MovieList {movieArray} />
{:catch error}
<div>Error loading movies: {error.message}</div>
{/await}
</div>
<style>
.main {
width: 500px;
max-width: 100%;
padding: 1em;
margin: auto;
text-align: center;
}
h1 {
color: #ff3e00;
text-transform: uppercase;
font-size: 4em;
font-weight: 100;
}
</style>
Adding MovieList as well, might be there that I'm doing something wrong:
And MovieList.svelte
<script>
export let movieArray;
</script>
{#each movieArray as movie}
<div>
<h3>{movie.title}</h3>
<p>Your Rating: {movie.rating}</p>
</div>
{/each}
<style>
div {
text-align: left;
padding-bottom: 10px;
border-bottom: 1px solid black;
}
</style>
If movies
holds a promise that resolves to an array of movies, the Svelte way is to use an {#await ...}
block:
<script>
import MovieInput from "./MovieInput.svelte";
import MovieList from "./MovieList.svelte";
import Search from "./Search.svelte";
import db from "./db.js";
import Dexie from "dexie";
// not needed, the resulting data array will be created within the
// {#await ...} block
// let movieArray = [];
//get a promise containing all movies in IndexedDB (if collection exists)
let movies = db.movies.count(function (value) {
return (movies = value > 0 ? db.movies.toArray() : []);
});
// not needed, use an {#await ...} block to handle resolution or error
// push items in promise to movieArray
// movies
// .then((movies) => {
// movies.forEach(function (movie) {
// movieArray.push(movie);
// });
// })
// .catch((error) => {
// console.log(error);
// }).finally(() => {
// movieArray = movieArray;
// });
//add new item to IndexedDb
const submitMovie = (movie) => {
db.movies.put({ title: movie.title, rating: movie.rating });
};
</script>
<div class="main">
<h1>Movie Journal</h1>
<MovieInput on:submitMovie={(event) => submitMovie(event.detail.movie)} />
{#await movies}
<div>Loading movies...</div>
{:then movieArray}
<MovieList {movieArray} />
{:catch error}
<div>Error loading movies: {error.message}</div>
{/await}
</div>
<style>
...
</style>