Our first 'Hello World' with VanJS, the new Mithril...
Tags: vanjs
Published: 2023-05-22 19:53:18

Every UI framerwork deserves its 'counter' example...

[SimpleCounter](https://flems.io/#0=N4IgtglgJlA2CmIBcAWATAOgBwDYA0IAZhAgM7IDaoAdgIZiJIgYAWALmLCAQMYD21NvEHIQAHigQAbgAIesWqVIBeADog2ENgnUA+VdRkyAarWoApAMoy2LeDICMGNAGsAQjICqASRmEATvTwAO58LgZiAPSSUvrUETEy0GogtAAOaXoGRhHR0nEG3CCk8Ag8mgLkTAAMSA4A7CAAvng0QaIYAFbkvAJCIkwQYGl8-mwyUmZ+-nxgMursbGmkSJGRk9TdGKMA5pH8UPDrZgC01RgOTgCcGJDUXaTqBgb81KTjwABGAK5sbAJ4GQxQEsBxNGTKCZmDBsWg7R7xaivd4yEYQQSkCFQ+7vWhCAAU1QAlM8kZVxuieFj8USIboZABqBlojEYSaweaIwjfJEVQwAQQyMhpMmA2Rk-ngbG+-kMiXx4qMoIVIFMsG+9iQ824qL46LYpCJeEVMh+fwE+OAAnkEB4LhkWspLW13gAcgBhdS08Uk6hNUkbDC0GD49JpQGCtI031FEplPlVEAOACsdSuZyQ1WarRAdAYHR4SiKr36bFEnz4UAAnqLxZ9aHadjMeVAtZ8FHaANzi-iwUZaqC0fwuUZmHbwbuGPx9E6EegkKtaocQWiwSf+xEwrQIWtToQADzYJ1XEB21CQPGEQn8k6MhBnpAgAC94Fq0JKwLfUcHJNQdlqAGZkzSfd11JABiMNdyMetG2bahWwlHZ63xNBk2TPAU3wao8HOBwiS-NIf3Rf8ZGqRxqhAmQ0Eo-cKJAr9gmgWw32TWivwPI8TzPC8r3gG861GQ5-C1BwqNIPhYGgGRRz-CdxTAIcdnRLVyNoX4+DAxEzX+QwxSnCt-GEpBqAEeSDIbFwmz4FskFk8dCOIv8tWA0DxXvQQTkfF86lcr8PKPYJ4FPdgkArWAoC-adPLnSBYEXGRl1XLSDDSSVoOio9vNfRxXIMJpY1KeByggSpRCwOoUGaABdJogA)

```js
import van from "https://vanjs.org/code/van-0.11.9.min.js"

const {button, div, h1} = van.tags

const points = van.state(0)

const inc = () => ++points.val 

function App () {
  return div (
    h1("Value : ", points),
    button({onclick : inc}, "INC") 
  )
}

van.add(app, App())
```
In the following example, the state is represented by an object instead of a single value, read the doc for more informations.
Beware the 'actions' object is my own 'business' and has nothing to do with VanJS.

[IncDec](https://flems.io/#0=N4IgtglgJlA2CmIBcAWATAOgBwDYA0IAZhAgM7IDaoAdgIZiJIgYAWALmLCAQMYD21NvEHIQAHigQAbgAIesWqVIBeADog2ENgnUA+VdRkyAarWoApAMoy2LeDICMGNAGsAQjICqASRmEATvTwAO58LgZiAPSSUvrUETEy0GogtAAOaXoGRhHR0nEG3CCk8Ag8mgLkTAAMSA4A7CAAvng0QaIYAFbkvAJCIkwQYGl8-mwyUmZ+-nxgMursbGmkSJGRk9TdGKMA5pH8UPDrZgC01RgOTgCcGJDUXaTqBgb81KTjwABGAK5sbAJ4GQxQEsBxNGTKCZmDBsWg7R7xaivd4ySywoQQqH3d60IQACmA2ShsG+9iQMmqBiaAEpnkjKuNaOUIJVMXi8TihNSIboZITDHIGTJSJjOfAMJNYABuIn+eBsb7+QwEolGCBImTkvHc5S8-lGA3C9HiyWY4AYC2kQGS0mamQAantpAltBJ8CaqpkLU9hx4du1PL5nqMYpdsDNFowVuJtvJJxOzpt7s94INRJpVOpeLRuPgtMRhG+SIqhgAghkZBzjdz9TI5QqlUDpJXPRsMJ91VAq7nARydbzQXj1KY3Xb1IDE67SdTqXhPT8-gICQJ5BAeC47UyS871TwWvMQN4AHIAYXUs-nv3+1GXSNga435K3LLeGF9+-UABEAKJnkDcol8w9RE21oGA8XSNJAXLNJs2rfM6SKEoym3UQ0CuJBqjOTDmlaEA6AYDoeCUIpXn6NhRE+PgoAATyDAVPiZFwdhmIsoHJT4FHXGUBX4WBRnJKBaH8FxRjMHZ4B4oxCD6E5CHoEgaKffwIFdHjgIMGEtAQeijCEAAPNgTldCAdmoJAeGEIR-CkvxZNICAAC94HJNA5TAWy0jAyRqB2ckAGYAFY0n09S6QAYkg3SZEY9cWL4NjyX8HZGLxNBAsCvAHEC-Bqjwc4HGpTzvPVPyKUcaoQpkNBKv0iqQts4JoFsVzAtq2yDKMkyzIsqz4BsokqP8Q5-HJBwqtIPh7ygGQxN8ySiTAYSdnVclqhkWhfj4MLEQXa9oqGkakGoAQFoYpj4sSuaJOKmBSvJYLQqJGTBATJyXOyhrntk4J4FM9gkCo2AoFsuzXvkyBYCUjaVLU1VDv6saJqm6AYq4lwdoMNI5Wil6jIc5yxseqkkNKeBmUqUQHAwhxmgAXQIAjGBAABZYxPFMCxLGaIA)

```js
import van from "https://vanjs.org/code/van-0.11.9.min.js"

const {button, div, h1} = van.tags

const State = van.state({
  value : 0
})

const actions = ((state) => {
  const s = state.val;
  return ({
    inc : () => {
      state.val = {...s, value : ++s.value}
    },
    dec : () => {
      state.val = {...s, value : --s.value}
    }    
  })
})(State)

function App (state) {
  return div (
    van.bind(state, (s) => h1("Value : ", s.value)),
    button({onclick : actions.inc}, "INC"),
    button({onclick : actions.dec}, "DEC") 
  )
}

van.add(app, App(State))

```
And for the final : multiple counters :

[MultipleCounters](https://flems.io/#0=N4IgtglgJlA2CmIBcAWATAOgBwDYA0IAZhAgM7IDaoAdgIZiJIgYAWALmLCAQMYD21NvEHIQAHigQAbgAIesWqVIBeADog2ENgnUA+VdRkyAarWoApAMoy2LeDICMGNAGsAQjICqASRmEATvTwAO58LgZiAPSSUvrUETEy0GogtAAOaXoGRhHR0nEG3CCk8Ag8mgLkTAAMSA4A7CAAvng0QaIYAFbkvAJCIkwGEGBpfP5sMlJmfv58YDLq7GxppEiRkVPU3RhjAOaR-FDwG2YAtNUYDk4AnBiQ1F2k6gYG-NSkE8AARgCubGwCPAyGJAlgOJoyZSTMwYNi0XZPeLUN4fGSWOFCSHQh4fWhCAAUwGy0NgP3g1RkSBk1TwxKmpPgDkp1NphhJZLQzOqBiaAEoXsjKhNaOUIJUsfj8bihLzIboZES2SiJqQsdL4Bh6QBuYn+eBsH7+QyE4lGCDI5n481HAAesuU8sVRmdMnVmtosCxwAwPtIQIoAAN6WSACTAa3wG1NAMAXWZAGp46RA8H4GGI1HY01TTIWjmjjxLRn7Y6c0Y3fSvT6MH6ZCmPaHw9RbdG41TTqdk0GG2mmy2szmIc7iXyebz8ei8fB+UjCD9kRVDABhPjzoT+KUY+BAjNY6qyp1GPUGo3A6QyfE5zYYL7WzdToFSksyMGXkCmBnM9RArup9PNyNW15XlWRdX5-gEQkBHkCAeBcS1nxFRdSAwc0eCtAC7RaBYQG8AA5Jd1BAnNwIBagoORWBYPgql8UQ0VKgwAsMNtXlsPUAARABRQiQFlYkZ2zWd5wYwwAEEMgvdUD11fVDUMGJLzZIwKGrMT-ECABPfEAGZeRjO50klAB9HdMOfFc13gDd1TM1iZyMQSBWvWgYHxdI0iBCS0gnLdgIFQoCBKMpkNEWpqlOFBwuaVoQDoBgOh4JQijefo2FEL4+CgTSFWJL4RRcXZZnnKAqS+BQ4J1JU+FgMYqSgWh-BcMYzF2eAqqMQg+lOQh6BITSqUaiAPSqoSDFhLQEFytkhBtNhTg9CBdmoJAeGEdcOr8brSAgAAveAqTQPUwE2tJXMkahdipHSAFY0htUaBQAYg86ajHyuCitXZsqX8XZ8vxNAbpuvAHBu-AaQuBxeVO87zSu6lHGqe6ZDQZGbSR+7NuCaBbEOm70c22b5sW5bVvW6zNsy-wjn8KkHBR0gaugGQWsu9riTARrdnNKkKVoP4+EepFSIEN6ZGp2mkGoAQObZD7CuKn62ba2GYHhqk7oe4kusETs9oOsGsZ17rgngJb2CQTLYCgTatr13rIFgAaZCGkbTUl6z6cZ5moAliqXGFgw0j1cXdfmnb9vprWeSKYL4FEqoQAca46maGMCHixgQAAWWMTxTAsSxmiAA)

```js

import van from "https://vanjs.org/code/van-0.11.9.min.js"

const {button, div, h1} = van.tags

// I could have use an array of values...
// But I wanted to play with dynamic properties
const State = van.state({
  value0 : 0,
  value1 : 0,
  value2 : 0
})

const actions = ((state) => {
  const s = state.val;
  return ({
    inc : (index) => {
      state.val = {...s, [`value${index}`] : ++s[`value${index}`]}
    },
    dec : (index) => {
      state.val = {...s, [`value${index}`] : --s[`value${index}`]}
    }    
  })
})(State)

function Counter(state, index = 0) {
   return div (
    van.bind(state, (s) => h1("Value : ", s[`value${index}`])),
    button({onclick : () => actions.inc(index)}, "INC"),
    button({onclick : () => actions.dec(index)}, "DEC") 
  )
}

function App (state) {
  return div(
    [...Array(3)].map((_, index) => Counter(state, index))
  )
}

van.add(app, App(State))

```

Here is an optimised version, thanks Tao [OpimisedMC](https://flems.io/#0=N4IgtglgJlA2CmIBcAWATAOgBwDYA0IAZhAgM7IDaoAdgIZiJIgYAWALmLCAQMYD21NvEHIQAHigQAbgAIesWqVIBeADog2ENgnUA+VdRkyAarWoApAMoy2LeDICMGNAGsAQjICqASRmEATvTwAO58LgZiAPSSUvrUETEy0GogtAAOaXoGRhHR0nEG3CCk8Ag8mgLkTAAMSA4A7CAAvng0QaIYAFbkvAJCIkwQYGl8-mwyUmZ+-nxgMursbGmkSJGRk9TdGKMA5pH8UPDrZgC01RgOTgCcGJDUXaTqBgb81KTjwABGAK5sbAJ4GQxQEsBxNGTKCZmDBsWg7R7xaivd4ySywoQQmTAbJQ2DfeDVGRIKH3d60IQACmqAEo8DjJnj4A4iSSMGTKTS6YZcfi0CyNmz0fAqbT6bRGQBmfnQ9nCzkGJrPJGVca0coQSqYikU2XUiG6LE4-zwNjffyGCnY7lGCBIlkU22HAAeeuUBpkAGoPTqhRQAAYM-EAEmAjvgTqafoAutSMAyZFyjEZDjx7WGXfqjCcTj7yfB-YH4CH05GY3HxTimtSFdSKWi89XEQZCN8kRVDABhPitoT+GS5oSA9N6q1GY2m81A6T9nFGUEU9RdnvwfwAfXUQ+ozsB6hZG5ksoL4uDoa34dLoutMh+fwEloE8ggPBc9tdBrV7dIGFtPAdZ5dLTzCA3gAHIduol5Jtevz-NQ95IrAT4vsSFJvjIH4am8GApn+zrUoB6gACIAKLgSAeo4nq8zUIqiItm2mEyAAghk-a6oa3LjmahgAPKfJ08DlBgLjwAAnqQdZCo2UG3Ok2qrpueGZkuggrgO8CKeGeqNrRBgCrQMAUukaSAixaSSQ2jaFAQJRlJ+ogShKSDVGcznNK0IB0AwHQ8EoRSvP0bCiJ8fBQKJHFGJ8aouDsMytlAxKfAoz4ANw4vwsCjMSUC0P4LijGYOzwGl3KEH0JyEPQJCicSuUQOKJW6fcmjaPYo42OGbAnOKEA7NQSA8MIvYlUYZWCCcpAQAAXvAxJoMaYAjTIaQGZI1A7MSEoAKxpE6jVKgAxMZEXXtFsXdluxL+DsUUUmgW1bXgDhbfg1R4OcDjUktK0wLaG0yISDjVLtMhoMDTqOODS3BNAthzVtUM4kITpdT1fUDUNK5LSF-iHP4xIOCDpB8IhUAyAV63FTiYC5TstrEoStC-Hw+2IjesEnTjeNINQAhU9yUXPud8VIBTRXfatf3Ejte04mNXWTTNdQy0t8snME8C9ewSAhbAUBLX45WVZAsA1eh-j1bABtcyuBNEyT0DXslLiswYaTGidauK7NjgywqRS2YJ9lMA4Vx1M0UYEF5jAgAAssYnimBYljNEAA)

```js
import van from "https://vanjs.org/code/van-0.11.9.min.js"

const {button, div, h1} = van.tags

const State = {
  value0 : van.state(0),
  value1 : van.state(0),
  value2 : van.state(0),
  value3 : van.state(0),
}

const actions = ((state) => {
  return ({
    inc : (index) =>  ++(state[`value${index}`]).val ,
    dec : (index) =>  --(state[`value${index}`]).val
  })
})(State)


function Counter (state, index) {
  return div (
    h1("Counter_", index, " : ", state[`value${index}`]),
    button({onclick : () => actions.inc(index)}, "INC"),
    button({onclick : () => actions.dec(index)}, "DEC") 
  )  
}

function App (state) {
  return Object.keys(State)
    .map((_, index) => Counter(state, index) )
}

van.add(app, App(State))

```