This post is my notes when creating All in pre Flop, a small svelte app used to determine the odds of winning a hand at hold’em.

Svelte is very easy to get started, the starter command creates a minimal project.

npx degit sveltejs/template all-in-pre-flop-svelte

cd all-in-pre-flop-svelte

npm install

This creates a project with the following npm scripts

"build": "rollup -c",
// builds the app for production (exports files into public folder)

"dev": "rollup -c -w",
// starts a server serving on localhost:5000, rebuilds the app every file change

"start": "sirv public"
// starts a server pointing to the public folder

There are no “controllers” in svelte, just components, these have extension .svelte, use the Atom svelte addon to have syntax highlighting.

The setup code for Svelte is small.

// src/main.js
// this is autogenerated for you
import App from './App.svelte';

const app = new App({ target: document.body });

export default app;

Import your top level component. This can be any svelte component, it will be used similar to “application” controller in ember

Attached the the component to the body on the document this will be assigned to index.html of the main project. For routing use Sapper or another library to create that app that spans more than one page.

Directory for a simple svelte app

├── package.json
├── public # place any img files or assets in public folder
│   ├── build/... # the bundle js and css files
│   ├── global.css
│   └── index.html # Add any <link> tags or edit title directly in index.html
├── rollup.config.js
├── node_modules/...
└── src
    ├── App.svelte
    ├── CardPicker.svelte
    └── main.js

In a .svelte file, you write html, to write javascript you add a <script></script> block and to add css you create a <style></style> block.

<script> block

The script block is executed when the component loads. In a script tag block, any variable initialized with let is accessible in the html portion of the file via {singleCurlyBrace} [1]

Something new I learned about javascript was the support for top level labels. Using the $ label is like a computed property in ember. If any variables used in the function definition assigned to it change throughout the life of the component, it will rerun and update the value of the given label. If the value is a reference, you must change the reference, adding/removing a field of an object, pushing/popping a value from array do not update the value of the computed property. [2]

Exporting a value using export let cardObj; allows whoever initializing the component to provide that value as a parameter.

Actions

To create an action used in the component, such as onclick, attach the event listener similar to regular html <section on:click={closeSelectionModal}> where closeSelectionModal is a function defined in the script block.

You can pass a function to a component using a “dispatcher.” by importing createEventDispatcher from 'svelte'. Calling this will create an event dispatcher to be used when wanting to call a function that was provied.

<!-- component B (inner component) -->
<script>
  import { createEventDispatcher } from 'svelte';
  const dispatch = createEventDispatcher();
  function updateCardChosen(inCard) {
    dispatch('updateCard', inCard);
  }
</script>

<button
  on:click={() => updateCardChosen({value: card})}>
  {card}
</button>

The dispatch('updateCard', inCard) fires an event that was proved to the component with inCard as it’s first parameter.

<!-- compoent A (outer component) -->
<ComponentB on:updateCard={card => card2 = card.detail} />

on:updateCard creates the event to call when dispatch is called, here we create an inline function with 1 parameter, but a function defined in a script block can be used as well. [3]

Html helpers

If statements in templates are similar to handlebars but only use one curly brace.

{#if}
  <p>something</p>
{else}
  <p>something else</p>
{/if}

For each block are also similar to ember/handlebars but do not require the iterator to be surrounded by pipe characters. You can also execute js statements within curly braces, like an .erb file. [4]

{#each suits as suit}
  <th class="fw6 bb b--black-20 pb3 pr3 {suit.isRed ? 'red' : ''}">{suit.icon}</th>
{/each}

Styles

You can use a style tag block to add styles. It creates class names that apply to only the component used and bundles them into a single css file. Or you can import your own library and use it app wide in the public folder.

1. [https://svelte.dev/docs#script](https://svelte.dev/docs#script) 2. [marks_a_statement_as_reactive](https://svelte.dev/docs#3_$_marks_a_statement_as_reactive) 3. [https://svelte.dev/docs#createEventDispatcher](https://svelte.dev/docs#createEventDispatcher) 4. [https://svelte.dev/docs#each](https://svelte.dev/docs#each)