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

[tutorial errata] #571

Open
warren-bank opened this issue Feb 1, 2024 · 14 comments
Open

[tutorial errata] #571

warren-bank opened this issue Feb 1, 2024 · 14 comments

Comments

@warren-bank
Copy link

warren-bank commented Feb 1, 2024

  1. Part 1 / Stores / Store bindings
    • tutorial
    • git
    • comments:
      • following:
        • The $name += '!' assignment is equivalent to name.set($name + '!').
      • addition:
        1. a note that this is also equivalent to:
          name.update(n => n + '!')
        2. a note about whether this is also equivalent to:
          name.update($name => $name + '!')
          • does $name have any special meaning in this context,
            or can it be used (for readability) as the name of this parameter?
        3. a note about whether there is any performance benefit in choosing one form vs. another
@warren-bank warren-bank changed the title [tutorial errata] just a few minor fixes that I noticed while reading [tutorial errata] Feb 5, 2024
@warren-bank warren-bank reopened this Feb 5, 2024
@Conduitry
Copy link
Member

I don't know that these sorts of things belong at this point in the tutorial. To answer some of these specific points: It's only equivalent to name.update(n => n + '!') if your store also implements the .update() method. The stores created by the exports from svelte/store so, but this is not guaranteed by the store contract. $name += '!' compiles to name.set($name + '!') which is guaranteed to work for all stores that satisfy the contract.

$name does not have special meaning when it's been shadowed by a local variable like a function parameter.

.set might be microscopically faster, but I don't think it would make any difference in the context of a real application.

@warren-bank
Copy link
Author

  1. Part 2 / Advanced bindings / Contenteditable bindings
    • tutorial
    • git
    • comments:
      • I may be nitpicking..
        but I believe that this example doesn't fully illustrate the concept
      • am I wrong to think that a better example might be:
          <script>
            let html = '<p>Write <b><i>some</i></b> text!</p>';
          </script>
        
          <div bind:textContent={html} contenteditable />
        
          <div>{@html html}</div>
        
          <style>
            [contenteditable] {
              padding: 0.5em;
              border: 1px solid #eee;
              border-radius: 4px;
              margin-bottom: 1em;
            }
          </style>
        

@warren-bank
Copy link
Author

  1. Part 3 / Routing / Pages
    • tutorial
    • git:
      1. on:change
      2. function set_iframe_src(src)
    • comments:
      • the theme configured for the tutorial is always used by the sample app that is rendered in an iframe
      • the tutorial allows the user to specify the relative URL (ie: route) that is rendered by the app
      • this relative URL should allow the user to override the global theme by specifying a ?theme= querystring parameter
        • ex: /about?theme=dark
      • however, this querystring value is updated by set_iframe_src immediately before the iframe is rendered
    • suggestion:
        /** @param {string} src */
        function set_iframe_src(src) {
          if (!iframe) return; // HMR
      
          // To prevent iframe flickering.
          // Set to `visible` by calling `set_iframe_visible` function
          // from iframe on:load or setTimeout
          iframe.style.visibility = 'hidden';
          setTimeout(set_iframe_visible, 1000);
      
          // removing the iframe from the document allows us to
          // change the src without adding a history entry, which
          // would make back/forward traversal very annoying
          const parentNode = /** @type {HTMLElement} */ (iframe.parentNode);
          parentNode?.removeChild(iframe);
      
          const url = new URL(src);
      
          if (!url.searchParams.has('theme'))
            url.searchParams.set('theme', $theme.current);
      
          iframe.src = url.href;
          parentNode?.appendChild(iframe);
        }
    • where:
      • the only change is the addition of a conditional test:
          if (!url.searchParams.has('theme'))
        before updating the theme querystring parameter

@warren-bank

This comment was marked as resolved.

@warren-bank

This comment was marked as off-topic.

@warren-bank

This comment was marked as off-topic.

@warren-bank

This comment was marked as off-topic.

@warren-bank

This comment was marked as off-topic.

@warren-bank

This comment was marked as off-topic.

@warren-bank

This comment was marked as off-topic.

@warren-bank

This comment was marked as off-topic.

@warren-bank
Copy link
Author

  1. Part 4 / Advanced routing / Breaking out of layouts
  • tutorial
  • example given:
    • src/routes/a/b/c/[email protected]
      • uses:
        • src/routes/+layout.svelte
      • ignores:
        • src/routes/a/b/c/+layout.svelte
  • comments:
    • the individual page resets its layout hierarchy to the root layout
    • should it not then also inherit the layout in its own directory?
  • questions:
    • can a layout hierarchy be reset for all descendent pages?
      • example:
        • src/routes/a/b/c/[email protected]
        • src/routes/a/b/c/+page.svelte
        • src/routes/a/b/c/d/+layout.svelte
        • src/routes/a/b/c/d/+page.svelte
          • such that it uses:
            • src/routes/+layout.svelte
            • src/routes/a/b/c/[email protected]
            • src/routes/a/b/c/d/+layout.svelte

@warren-bank
Copy link
Author

  1. Docs: CORE CONCEPTS / Loading data / Using parent data
    • docs
    • git
    • comments:
      • fair warning… to avoid waterfalls
      • the given implementation does not do that
        • 2 Promises are resolved synchronously
        • the order doesn't matter
      • a better implementation might more closely resemble:
          export async function load({ params, parent }) {
            const [parentData, data] = await Promise.all([
              parent(),
              getData(params)
            ]);
        
            return {
              ...data
              meta: { ...parentData.meta, ...data.meta }
            };
          }

@warren-bank

This comment was marked as off-topic.

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

2 participants