I'm trying to implement a fairly standard blog app using Svelte, Svelte Routing and Firestore, but I think I'm misunderstanding a fundamental part of how props are passed between ponents.
I based my initial code on the excellent tutorial on Fireship.io - which worked as per the tutorial: /
From there I've added Svelte Routing - - and I'm attempting to add a view route.
Relevant part of App.svelte:
<Router url="{url}">
<Navbar user="{user}" />
<div>
<Route path="posts/:id" ponent="{Post}" />
<Route path="posts/add" ponent="{PostForm}" />
<Route path="posts" ponent="{Blog}" />
<Route path="/" ponent="{Home}" />
</div>
</Router>
In my Blog Component I use a ponent called PostTeaser, in which I pass a link to the post view page.
Blog Component:
<div class="posts">
{#each posts as post}
<PostTeaser post="{post}" />
{/each}
</div>
PostTeaser ponent:
<div class="post-teaser">
<h2 class="title is-3"><Link to="posts/{ post.id }" {post}>{ post.title }</Link></h2>
<div class="post-teaser-content">{ post.content }</div>
</div>
Here I get a warning in the browser:
<Link> was created with unknown prop 'post'
Although the teaser does appear on the screen with the correct information.
When I click through to the post, i.e. the Post Component, my data is undefined.
I am placing export let post;
in the script tag of each of my ponents.
Should I be using a "store" for my data? At the moment I'm fetching my data in the BlogComponent and passing it down the line. It would seem that this is incorrect. Any help gratefully appreciated.
See here for fuller example:
I'm trying to implement a fairly standard blog app using Svelte, Svelte Routing and Firestore, but I think I'm misunderstanding a fundamental part of how props are passed between ponents.
I based my initial code on the excellent tutorial on Fireship.io - which worked as per the tutorial: https://fireship.io/lessons/svelte-v3-overview-firebase/
From there I've added Svelte Routing - https://github./EmilTholin/svelte-routing - and I'm attempting to add a view route.
Relevant part of App.svelte:
<Router url="{url}">
<Navbar user="{user}" />
<div>
<Route path="posts/:id" ponent="{Post}" />
<Route path="posts/add" ponent="{PostForm}" />
<Route path="posts" ponent="{Blog}" />
<Route path="/" ponent="{Home}" />
</div>
</Router>
In my Blog Component I use a ponent called PostTeaser, in which I pass a link to the post view page.
Blog Component:
<div class="posts">
{#each posts as post}
<PostTeaser post="{post}" />
{/each}
</div>
PostTeaser ponent:
<div class="post-teaser">
<h2 class="title is-3"><Link to="posts/{ post.id }" {post}>{ post.title }</Link></h2>
<div class="post-teaser-content">{ post.content }</div>
</div>
Here I get a warning in the browser:
<Link> was created with unknown prop 'post'
Although the teaser does appear on the screen with the correct information.
When I click through to the post, i.e. the Post Component, my data is undefined.
I am placing export let post;
in the script tag of each of my ponents.
Should I be using a "store" for my data? At the moment I'm fetching my data in the BlogComponent and passing it down the line. It would seem that this is incorrect. Any help gratefully appreciated.
See here for fuller example: https://codesandbox.io/s/romantic-cannon-ri8lo
Share Improve this question edited Jun 23, 2019 at 11:47 Martin Petts asked Jun 23, 2019 at 9:17 Martin PettsMartin Petts 5132 gold badges7 silver badges15 bronze badges2 Answers
Reset to default 5With svelte-routing, you don't pass props from the <Link>
ponent, you pass them from the <Route>
ponent implicitly. Where you have this...
<Route path="posts/:id" ponent="{Post}" />
...you're telling the router that if the URL matches the pattern /posts/:id
, it should render the Post
ponent, passing it an id
prop that matches that part of the URL.
The Post
ponent is responsible for fetching its data based on that. So in this case, you could move the posts
array into a separate module, and change Post.svelte
accordingly:
<script>
import posts from "./posts.js";
export let id;
$: post = posts.find(p => p.id == id);
</script>
<div class="post">
<h1>{ post.title }</h1>
<div class="post-content">{ post.content }</div>
</div>
(Note that props are stringified because they're derived from the href
, so we need a ==
parison rather than ===
.)
Here's a working fork.
Simple example:
Parent Component
<script>
import PostTeaser from "./PostTeaser.svelte";
let post = {
first: 'First prop',
second: 'Second prop'
};
</script>
<PostTeaser {...post} />
Child Component
<script>
export let first;
export let second;
</script>
First prop: {first} <br>
Second prop: {second}
Code here: https://codesandbox.io/s/spread-props-using-svelte-y7xou