GithubHelp home page GithubHelp logo

arecvlohe / purs-medellin-workshop Goto Github PK

View Code? Open in Web Editor NEW
5.0 1.0 2.0 20 KB

PureScript and Pux Workshop for JSConf Medellin

PureScript 84.68% HTML 15.32%
purescript purescript-demo purescript-pux pux pux-module

purs-medellin-workshop's Introduction

PureScript Workshop for JSConf Medellín

Lesson 1: Getting Started

  1. Install psc-package and pulp
npm i -g psc-package pulp
  1. Initialize the project
pulp --psc-package init
  1. Build the project
pulp --psc-package run
  1. Do your happy dance!
My first PureScript project 🕺

Part 2: Resources and Creating a Bundle

Resources

  1. PureScript by Example (Free eBook)
  2. Let's Build a Simon Game in PureScript
  3. PureScript Cheatsheet
  4. PureScript Slack Channel

Bundle

  1. Creat an index.html at the root of your directory
touch index.html
  1. Add basic html markup
<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
  </head>

  <body>
    <script src='./output/app.js'></script>
  </body>

</html>
  1. Run the server
pulp server
  1. Do your happy dance!
My first PureScript app 💃

Part 3: Hello Pux!

  1. Install Pux
psc-package install pux
  1. Imports
import Prelude hiding (div)
import Control.Monad.Eff (Eff)
import Pux (CoreEffects, EffModel, start)
import Pux.DOM.Events (onClick)
import Pux.DOM.HTML (HTML)
import Pux.Renderer.React (renderToDOM)
import Text.Smolder.HTML (button, div, span)
import Text.Smolder.Markup (text, (#!))
  1. User Actions
data Event = Increment | Decrement
  1. State
type State = Int
  1. Update
foldp ::  fx. Event -> State -> EffModel State Event fx
foldp Increment n = { state: n + 1, effects: [] }
foldp Decrement n = { state: n - 1, effects: [] }
  1. View
view :: State -> HTML Event
view count =
  div do
    button #! onClick (const Increment) $ text "Increment"
    span $ text (show count)
    button #! onClick (const Decrement) $ text "Decrement"
  1. Main
main ::  fx. Eff (CoreEffects fx) Unit
main = do
  app <- start
    { initialState: 0
    , view
    , foldp
    , inputs: []
    }

  renderToDOM "#app" app.markup app.input
  1. Mount App and Add React
 <body>
    <div id="app"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
    <script src='./output/app.js'></script>
  </body>
  1. Bundle and Serve
pulp server
  1. Do your happy dance!
My first PureScript app that does something 🕺 💃

Part 4: Add Effects

  1. Install the aff module
psc-package install aff
  1. Import modules
import Control.Monad.Aff.Console (CONSOLE, log)
import Data.Maybe (Maybe(..)) -- Part of Prelude
  1. Define App Effects
type AppEffects = ( console:: CONSOLE )
  1. Log state to console
foldp ::  fx. Event -> State -> EffModel State Event AppEffects -- 👈
foldp Increment n = { state: n + 1, effects: [
  do
    log $ "Current State: " <> (show $ n + 1)
    pure Nothing
]}
foldp Decrement n = { state: n - 1, effects: [
  do
    log $ "Current State: " <> (show $ n - 1)
    pure Nothing
]}
  1. Update Main
main ::  fx. Eff (CoreEffects AppEffects) Unit -- 👈
main = do
  app <- start
    { initialState: 0
    , view
    , foldp
    , inputs: []
    }

  renderToDOM "#app" app.markup app.input
  1. Run server
pulp server
  1. Do your happy dance!
My first PureScript side-effect 🕺

Part 5: HTTP Side-Effect

  1. Install necessary modules
psc-package install argonaut-codecs affjax
  1. Import modules
import Control.Monad.Aff (attempt)
import Data.Argonaut.Decode (decodeJson, (.?))
import Data.Argonaut.Decode.Class (class DecodeJson)
import Data.Either (Either(Left, Right), either)
import Data.Newtype (class Newtype, un)
import Network.HTTP.Affjax (AJAX, get)

import Text.Smolder.HTML (button, div, img)
import Text.Smolder.HTML.Attributes (src)
import Text.Smolder.Markup (text, (#!), (!))
  1. Define effects
type AppEffects = ( console:: CONSOLE, ajax:: AJAX )
  1. Define user actions
data Event = RequestGiphy | ReceiveGiphy (Either String Url)
  1. Define a newtype (for decoding)
newtype Url = Url String

derive instance newtypeUrl :: Newtype Url _

unwrap :: Url -> String
unwrap = un Url
  1. Define the state
type State = Url
  1. Decoder
instance decodeJsonUrl :: DecodeJson Url where
  decodeJson json = do
    obj <- decodeJson json
    info <- obj .? "data"
    imgUrl <- info .? "image_original_url"
    pure $ Url imgUrl
  1. Update
foldp ::  fx. Event -> State -> EffModel State Event AppEffects
foldp RequestGiphy state = { state: state, effects: [
  do
    result <- attempt $ get "https://api.giphy.com/v1/gifs/random?api_key=670526ba3bda46629f097f67890105ed&tag=&rating=G"
    let decode res = decodeJson res.response :: Either String Url
    let url = either (Left <<< show) decode result
    pure $ Just $ ReceiveGiphy url
]}
foldp (ReceiveGiphy (Left _)) state = { state: state, effects: [ log "Error" *> pure Nothing ] }
foldp (ReceiveGiphy (Right url)) state = { state: url, effects: [ log "ReceivedGiphy" *> pure Nothing ]}
  1. View
view url =
  div do
    button #! onClick (const RequestGiphy) $ text "Get Random Giphy"
    img ! src (unwrap url)
  1. Main
main ::  fx. Eff (CoreEffects AppEffects) Unit
main = do
  app <- start
    { initialState: Url "" -- 👈
    , view
    , foldp
    , inputs: []
    }

  renderToDOM "#app" app.markup app.input
  1. Run server
pulp server
  1. Do your happy dance!
My first PureScript HTTP request 🕺 💃

Part 6: Make request from user input

  1. Update Imports
import Pux.DOM.Events (onClick, onChange, DOMEvent, targetValue)
import Text.Smolder.HTML (button, div, img, input)
import Text.Smolder.HTML.Attributes (src, type', value)
  1. Update state
type State =
  { url :: Url
  , input :: String
  }
  1. Update
foldp ::  fx. Event -> State -> EffModel State Event AppEffects
foldp RequestGiphy state = { state: state, effects: [
  do
    result <- attempt $ get $ "https://api.giphy.com/v1/gifs/random?api_key=670526ba3bda46629f097f67890105ed&tag=" <> state.input <> "&rating=G"
    let decode res = decodeJson res.response :: Either String Url
    let url = either (Left <<< show) decode result
    pure $ Just $ ReceiveGiphy url
]}
foldp (ReceiveGiphy (Left _)) state = { state: state, effects: [ log "Error" *> pure Nothing ] }
foldp (ReceiveGiphy (Right url)) state = { state: state { url = url }, effects: [ log "ReceivedGiphy" *> pure Nothing ]}
foldp (UserInput ev) state = { state: state { input = targetValue ev }, effects: [] }
  1. View
view state =
  div do
    input ! type' "text" #! onChange UserInput ! value state.input
    button #! onClick (const RequestGiphy) $ text "Get Random Giphy"
    img ! src (unwrap state.url)
  1. Main
main ::  fx. Eff (CoreEffects AppEffects) Unit
main = do
  app <- start
    { initialState: { input: "", url: Url "" } -- 👈
    , view
    , foldp
    , inputs: []
    }

  renderToDOM "#app" app.markup app.input
  1. Run server
pulp server
  1. Do your happy dance!
My first PureScript Giphy App 💃

purs-medellin-workshop's People

Contributors

arecvlohe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.