question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[feat] helper for creating stores

See original GitHub issue

Describe the problem

You can’t just blindly create a store in SSR or it’ll end up being a global store shared by all users (https://github.com/sveltejs/kit/discussions/4339). We should provide a helper that ties it to the request.

Describe the proposed solution

At the very least we can make it part of the Svelte context. SvelteKit does this internally with its own stores.

I wonder if we couldn’t make it available earlier. If we only make it part of the Svelte context then you can’t use it in load. If we additionally tied it to the request it would be available throughout the rendering of the request.

We could have an API like:

export const getStore = function(key, request) {
  return request ? WEAK_MAP.get(request).get(key) : getContext(key);
};

When we’re going to start rendering the templates we could populate the context from the map.

We could also have a method to create a store. Being able to call it in handle would solve https://github.com/sveltejs/kit/issues/7107:

createStore(request, 'whatever', request.locals.whatever);

There are a couple things we might make optional. E.g. we could potentially look for 'whatever' in locals automatically. Or we could make the request optional - if it’s not provided the store would only be available in the template (at least on the server).

Alternatives considered

The user could create the store themselves if we just want it available in the template. That starts getting cumbersome if they want it available either as a singleton in the browser or tied to the request on the server. It’s impossible if they want to populate it from locals

Some of the APIs I’ve proposed here may be open for debate on the actual details

Importance

would make my life easier

Additional Information

No response

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:18
  • Comments:19 (19 by maintainers)

github_iconTop GitHub Comments

5reactions
dummdidummcommented, Nov 7, 2022

I long wanted to write a “State Management” section for the docs, where we also can note the “careful what to put on the server, it’s shared for all requests”-stuff. This pattern could also go in there.

3reactions
david-pluggecommented, Oct 18, 2022

An issue i´ve run into a few times now is not beeing able to update $page.data client side.

Example:

You display some database rows in your app and add another row. You call fetch and post the data to a +server endpoint or make use of the form actions. The only option (that i know of) to get the added row is to call invalidate and reload all page related data. This will obviously result in twice the network calls compared to just adding the newly created data to $page.data.

One way i´ve solved this:

import { invalid } from '@sveltejs/kit';
import type { PageServerLoad, Actions } from './$types';

export const load: PageServerLoad = async () => {
	return {
		// just some random test data
		posts: [{ title: 'Post 1' }, { title: 'Post 2' }, { title: 'Post 3' }]
	};
};

export const actions: Actions = {
	async addPost({ request }) {
		const data = await request.formData();
		const title = data.get('title') as string;

		if (!title) {
			return invalid(400, {
				titleMissing: true
			});
		}
		return {
			newPost: { title }
		};
	}
};

make it a store in +page.ts

export const load: PageLoad = ({ data }) => {
	return {
		posts: writable(data.posts)
	}
}

and update that store inside +page.svelte

<script lang="ts">
	import { applyAction, enhance, type SubmitFunction } from '$app/forms';
	import type { PageData, ActionData } from './$types';

	export let form: ActionData;
	export let data: PageData;

	$: posts = data.posts;

	const handleAddPost: SubmitFunction<{ newPost: { title: string } }> =
		() =>
		async ({ result, update }) => {
			if (result.type === 'success') {
				await applyAction(result);

				posts.update(($posts) => {
					$posts.push(result.data!.newPost);
					return $posts;
				});
				return;
			}
			update();
		};
</script>

<ul>
	{#each $posts as item}
		<li>{item.title}</li>
	{/each}
</ul>

<form action="?/addPost" method="post" use:enhance={handleAddPost}>
	{#if form?.titleMissing}
		<p class="error">Please enter a title</p>
	{/if}
	<input name="title" type="text" placeholder="Title" />
	<button type="submit">Submit</button>
</form>

I´m just curious if this api/helper, if it´s going to be a thing, will provide an easier way to get writable stores from the client to the server in such use cases.

Read more comments on GitHub >

github_iconTop Results From Across the Web

feat: option to import helper methods instead of inlining them ...
Problem Currently, when applying syntax transformations via transform API, helper methods are inlined to the top of the file.
Read more >
Handbooker Helper: Feats - YouTube
... is here to provide all the deets on feats in D&D 5e with another informative installment of Handbooker Helper ! Featuring doodles...
Read more >
New Ways for Creators and Brands to Connect and ...
Instagram is introducing a suite of new tools to help creators and brands connect and collaborate through brand partnerships, commerce and ...
Read more >
8 Time-Consuming Business Tasks—and How to Automate ...
Save time with bots that automate your Shopify store. Ecommerce automation tools can help you with marketing, data, and more.
Read more >
14.5 in. Aluminum Nonstick Create Delicious Frying Pan with ...
Aluminum Nonstick Create Delicious Frying Pan with Helper Handle in Gray Shimmer. (1) ... Featuring vibrant, shimmering color combined with value-driven ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found