Halogen confusion

I’m pretty new to purescript (or functional programming in general) and halogen and I’m trying to build a simple application for myself. I’ve managed to build other things in purescript successfully, but I seem to be unable to understand halogen correctly.

What I am trying to build:

  • An application that allows to upload a text file upon pressing a button
  • Render a list with the information given by that file (there’s some parsing involved - the parsing is no problem)
module Main where

import Prelude

import DOM.HTML.Indexed.InputAcceptType (InputAcceptTypeAtom(..))
import Data.Array (fromFoldable)
import Data.Either (Either(..))
import Data.Foldable (traverse_)
import Data.Maybe (Maybe)
import Effect (Effect)
import Effect.Aff.Class (class MonadAff)
import Halogen as H
import Halogen.Aff (awaitBody, runHalogenAff)
import Halogen.HTML as HH
import Halogen.HTML.Events as HE
import Halogen.HTML.Properties as HP
import Halogen.VDom.Driver (runUI)
import Parsing (runParser)
import Parsing.Combinators (many)
import VCF.Reader.V2 (single)
import VCF.Type.VCard (VCard, postProcess)
import Web.File.File (File, toBlob)
import Web.File.FileReader.Aff (readAsText)

data HomeAction = FileChosen (Maybe File)

type State =
  { items :: Array VCard
  , editing :: Int

homeComponent :: forall q i o m. MonadAff m => H.Component q i o m
homeComponent =
    { initialState
    , render
    , eval: H.mkEval $ H.defaultEval { handleAction = eval }

initialState :: forall i. i -> State
initialState _ =
  { items: []
  , editing: -1

render :: forall m. State -> H.ComponentHTML HomeAction () m
render _ =
    [ HP.type_ HP.InputFile
    , HP.id "file-selector"
    , HP.accept $ HP.InputAcceptType $ [ AcceptFileExtension ".vcf" ]
    , HE.onFileUpload \f -> FileChosen f

eval :: forall o m. MonadAff m => HomeAction -> H.HalogenM State HomeAction () o m Unit
eval action = case action of
  FileChosen f → do
    traverse_ handleFileUpload f
    handleFileUpload :: forall oo mm. MonadAff mm => File -> H.HalogenM State HomeAction () oo mm Unit
    handleFileUpload file = do
      content ← H.liftAff $ readAsText (toBlob file)
      case runParser content (many (single true)) of
        Right items -> H.modify_ _
          { items = fromFoldable $ map (\e -> postProcess e) items
        Left _ -> pure unit

main :: Effect Unit
main = runHalogenAff do
  body <- awaitBody
  runUI homeComponent unit body

I have the fileUploadButton thing working correctly (I think). I felt like creating a new component for the listview, since there will be the list, some buttons, etc in that. I’ve looked through examples and the halogen guide, but I cannot seem to understand how to create a child component…

Is someone able to help me?

1 Like


sure I can try to help you - have you tried anything yet an run into issues or are you stuck on where to look next?

I’m asking because at this point I can give you not much more than a hint to or something similar like the example from the docs which is a good start here I think.

1 Like

Thank you, I figured it out. Took a bit of time.
What helped a lot was checking the examples after reading the docs you mentioned. I somehow overlooked them.

1 Like