Help figuring out Web.HTML & Web.DOM (or just unwraping a maybe)

I am coming from an intermediate Haskell background (and before that Python, Perl, C et al.)

I am trying to learn Purescript to do front end development (for the first time). I’ve realized that I’m essentialy learning two things at once here.

I have the following code, trying to do some simple DOM manipulation using Web.HTML and Web.DOM. Everything seems to work until I try to use the appendChild function (or possibly it’s due to my improper unwrapping of a datum that is a Maybe Element??).

Here’s my code so far:

module Main where

import Prelude

import Data.Maybe (Maybe(..), fromMaybe)
import Effect (Effect)
import Effect.Console (log)
import Web.HTML (window)
import Web.HTML.Window (document)
import Web.HTML.HTMLDocument (toNonElementParentNode, toDocument)
--import Web.HTML.HTMLDocument (toParentNode, HTMLDocument)
import Web.DOM.Element (Element, toNode, setId)
import Web.DOM.NonElementParentNode (getElementById)
import Web.DOM.Node (textContent, setTextContent, appendChild)
import Web.DOM.Document (createElement)
import Debug.Trace (traceM)


maybeText :: Maybe Element -> Effect String
maybeText (Just el) = textContent  (toNode el)
maybeText _         = pure ""

main :: Effect Unit
main = do

  -- Web.HTML (window)
  --   window :: Effect Window
  w <- window

  -- Web.HTML.Window (document)
  --   document :: Window -> Effect HTMLDocument
  d <- document w

  -- Web.HTML.HTMLDocument (toNonElementParentNode)
  --         toNonElementParentNode :: HTMLDocument -> NonElementParentNode
  let pofd = toNonElementParentNode d

  --              getElementById :: String  -> NonElementParentNode -> Effect (Maybe Element)
  elem_content <- getElementById    "content"  pofd


  --                  maybeText :: Maybe Element -> Effect String
  elem_content_str <- maybeText  elem_content

  -- log :: String -> Effect Unit
  log $ "content id contains: " <> elem_content_str


  -- toDocument :: HTMLDocument -> Document
  let d_plain = toDocument d

  --   const item3Element = document.createElement("li"); // Create an "li" element
  --          createElement  :: String -> Document -> Effect Element
  elem_item3 <- createElement     "li"      d_plain


  --   item3Element.id = "item3";          // Define element ID
  -- setId :: String -> Element -> Effect Unit
  setId       "item3"   elem_item3

  --   item3Element.textContent = "Item 3"; // Define its text content
  -- toNode :: Element -> Node
  -- setTextContent :: String  -> Node              -> Effect Unit
  setTextContent       "Item 3" $ toNode elem_item3


  --                           fromMaybe :: forall a. a            -> Maybe a          -> a
  --                           fromMaybe ::           Element      -> Maybe Element    -> a
  let elem_content_unwrapped = fromMaybe              (elem_item3)    (elem_content)

  --   document.getElementById("content")
  --           .appendChild(item3Element); // Insert the new element into the DOM
  -- toNode :: Element -> Node
  -- appendChild :: Node               -> Node                           -> Effect Node
  appendChild       (toNode elem_item3)   (toNode elem_content_unwrapped)


  log "end" -- dummy last command

The specific error I’m getting is:

Error found:
in module Main
at src/Main.purs:83:3 - 85:36 (line 83, column 3 - line 85, column 36)

  A result of type
        
    Node
        
  was implicitly discarded in a do notation block.
  You can use _ <- ... to explicitly discard the result.

while applying a function discard
  of type Discard t0 => Bind t1 => t1 t0 -> (t0 -> t1 t2) -> t1 t2
  to argument (appendChild (toNode elem_new)) (toNode elem_content_unwrapped)
while inferring the type of discard ((appendChild (toNode elem_new)) (toNode elem_content_unwrapped))
in value declaration main

where t0 is an unknown type
      t2 is an unknown type
      t1 is an unknown type

See https://github.com/purescript/documentation/blob/master/errors/NoInstanceFound.md for more information,
or to contribute content related to this error.


[error] Failed to build.

I have tried several things here, such that I’m not sure that I’m thinking straight any more.

If you change the problematic line from

appendChild (toNode elem_item3) (toNode elem_content_unwrapped)

to

ignored <- appendChild (toNode elem_item3) (toNode elem_content_unwrapped)

It will compile.

This is the important piece of the error message:

 A result of type
       
   Node
       
 was implicitly discarded in a do notation block.
 You can use _ <- ... to explicitly discard the result.

Not sure if it does what you want though. If it’s still not working, a link to your project repo (with accompanying index.html) would make troubleshooting easier for forum readers.

I’m not sure what your project goals are, but Web.HTML and Web.DOM might be a bit low-level for general frontend development. You may have more success using a framework like react-basic-hooks or halogen, even if they seem like more complexity to learn upfront.

Here are two starter projects that will get you going in either framework with reasonable tooling:

Additional learning resources are:

I had seen that, but was doing a _ <- on the wrong line. Reading through the error again, I see that it was indeed the appendChild with the problem. This did both get the code to compile and it worked!

Thanks for the help!

I have seen both the react stuff (which I’m not sure I want to dive into) and Halogen. I have been collecting links about and tutorials for Halogen. However, I have to really dive in deep to understand things “from first principles” before going higher up in abstractions. So, my plan is to understand how to do the simple things (well, simple in JS, not so simple given the existing libraries), then move on to really master Halogen. On this path, my hope is that I’ll master the different in purescript as well.

@senorsmile For context as to why this error occurs, see Discard.md

1 Like