Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can't supply store to nested components server side #1107

Closed
jamesbirtles opened this issue Jan 14, 2018 · 3 comments
Closed

can't supply store to nested components server side #1107

jamesbirtles opened this issue Jan 14, 2018 · 3 comments

Comments

@jamesbirtles
Copy link
Contributor

Hey, I'm trying to pass a store to a nested component which works well ordinarily, but it fails when server rendering it.

E.g. I have a manage account page like so:

<div class="page">
    <h1>Manage Account</h1>

    <div>
        <h3>Two Factor Auth</h3>
        <TwoFactorAuth />
    </div>
</div>

<style>
    .page {
        width: 400px;
        margin: 50px auto;
    }
</style>

<script>
    import TwoFactorAuth from './_components/TwoFactorAuth';

    export default {
        components: {
            TwoFactorAuth,
        },
    }
</script>

And in the TwoFactorAuth component, using a store via svelte-redux

{{#if $hasTwoFactor}}
<div>yay its enabled</div>
{{else}}
<div>oh no its not enabled</div>
{{/if}}

<script>
    import { connect } from '../../_redux';

    export default {
        store: connect(state => ({
            hasTwoFactor: state.user && state.user.hasTwoFactor,
        })),
    }
</script>

As mentioned this fails on the server side, but not when navigation to the page on the client side.

I dug into the generated code a bit and I see it generates the template like so:

return `<div class="page" svelte-1782208320>
    <h1>Manage Account</h1>

    <div>
        <h3>Two Factor Auth</h3>
        ${__WEBPACK_IMPORTED_MODULE_0__components_TwoFactorAuth__["a" /* default */]._render(__result, {}, { store: options.store })}
    </div>
</div>`

This is bypassing render where the store would be initialised ordinarily, and is instead just passing the parent store.

It errors on the following line in the TwoFactorAuth's _render method, as the store is undefined

state = Object.assign(options.store._init(["hasTwoFactor"]), state);
Cannot read property '_init' of undefined
@arxpoetica
Copy link
Member

Sorry I'm not answering your question in full, but just a quick pointer, generally speaking using the underlying internals (anything starting with _ such as _init) is frowned upon. The suggested approach is to use the official API. If you think there's something missing from the API to make the above possible, bring it up here as a suggestion, and we'll take a deeper look into it.

@jamesbirtles
Copy link
Contributor Author

The use of svelte-redux makes zero difference here, it errors just the same using a regular store. I was just being a bit lazy when it came to providing the example. Here is a gist that shows the same issue using the vanilla store.

As for using internals of the api, if there was any suggestion it would be take exactly what there is now but make it public, allowing for third party stores that don't extend the built in store itself.

@Rich-Harris
Copy link
Member

Released 1.52 with the fix. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants