Hi,
How can I fix this error?
The List.map accountRow accountslist
will produce an array of DIV rows. e.g. [ div[] [], div [] [], …]
But I want to wrap them into a parent DIV.
Hi,
How can I fix this error?
The List.map accountRow accountslist
will produce an array of DIV rows. e.g. [ div[] [], div [] [], …]
But I want to wrap them into a parent DIV.
The second argument to div
has to be a list of HTML elements and your List.map
call return sich a list. But then you surround it with square brackets, producing a list of lists (although the outer list contains only one element). So the solution is to replace the square brackets around the List.map
call by parentheses.
I have tried that already, same error.
It seems like what should work is List.map accountRow accountslist |> div []
but I’m getting error on another place.
List.map accountRow accountslist |> div []
, div [] <| List.map accountRow accountslist
and div [] (List.map accountRow accountslist)
are all equivalent and any of them should work for the error you show here.
The error that I am now getting is this
Yes, that’s a different error. Most likely you need to change the signature of contentFinal
to Content msg
You cannot have a Html Msg
inside a Html msg
.
Also, for the fun of it, I have refactored your code:
viewAccountList accounts =
div [ class "row" ]
[ div [ class "col-md-4" ] [ text "Id" ]
, div [ class "col-md-4" ] [ text "Code" ]
, div [ class "col-md-4" ] [ text "Title" ]
]
:: List.map accountRow accountsList
|> div []
viewAccounts accounts =
Maybe.map viewAccountList accounts
|> Maybe.withDefault (p [] [ text "No records to show" ])
|> contentFinal
The issue looks like is you “view function” signature instead “-> Html msg” needs to be “-> Html Msg” essentially the “msg” in lower case is a place holder type and the compiler detected that your code is using the “Msg”. You can check this thread that has better explanation. Html Msg vs Html msg?
Thanks for refactoring. Appreciate that, beginner like will learn from the feedback. I’m trying that out now.
Btw, I have this separate PageContent.elm file imported which I’d like to be the base content of all the sub pages.
`
module Page.PageContent exposing (…)
import Html exposing (…)
type alias Content msg =
{ title : String
, content : List (Html msg)
}
`
Example from my Homepage:
`module Page.Home exposing (…)
import Html exposing (…)
import Html.Attributes exposing (…)
import Page.PageContent as PC exposing (…)
homePage : PC.Content msg
homePage =
{ title = “Home”
, content = p [] [ text “Home Page” ]
}
`
All the Html
created in Elm will end up in one of the browser functions.
If the Html
has event handlers, then the function that includes that Html has to have a concrete type in its return (e.g. Html Msg
not Html msg
). All the functions that call this function have to have concrete type in their return.
So it seems like I need to get rid of my PageContent.elm and use Html Msg
to all?
That helper is OK. It’s just a decorator and is fine to have msg
.
You need to be careful when you use it. For example, the signature for homePage
is fine the way it is right now BUT somePage
that has event handlers should be somePage : PC.Content Msg
Yeah, that’s true. I like the idea of having this pretty small helper to handle the title and content. For a simple page like Home it’s not a problem. But when I started to use in a page with logic I got messed up. My project still small I guess.
It’s 6 KB in zip. I can send it to you if your willing to continue to assist. Thanks
If possible, put it in a github repository and I’ll take a look .
Here is the github repo https://github.com/mvperez/elm-spa.git
I will greatly appreciate if you can refactor things more I can study.
Thank you so much!
There were only two errors in the code:
First is a common one for people just starting out: you need to Html.map
the view message type from the page type to the main type. Like this:
contentPage : Model -> Html Msg
contentPage model =
let
page =
case model.page of
HomePage ->
Home.homePage
ListAccountsPage pageModel ->
let
content =
Accounts.view pageModel
|> Html.map ListAccountsOnGet
in
content
AboutPage ->
About.aboutPage
in
page
Also, the ListAccountsOnGet
should be ListAccountsMsg
. The wrapper is for all messages in the Page.Msg
The second error was in the main view. It should be like this:
view : Model -> Browser.Document Msg
view model =
let
content =
contentPage model
log1 =
log "Page Content => " content
in
{ title = "Accounting"
, body =
[ ul []
[ viewLink "/" "home"
, viewLink "/about" "about"
, viewLink "/accounts" "accounts"
]
, content
]
}
For some reason, instead of content
you had content.content
. If you actually expected that to work, it might be helpful to explain your reasoning for content.content
as this might lead to more learning.
Some things are tricky in the beginning.
Thanks @pdamoc! Appreciate much. The content.content
is because I previously had PageContent helper that has {title: String, content: List (Html msg)}
which I already remove. If I still have that, I’m just display the .content
. I will apply your changes. Then after that I need to study my code again.
This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.