0
votes

I have a Yesod handler that is returning a list of type [(Category, [Product])] I am trying to loop through this in my hamlet template.

$if null rows
    <p>No products
$else
  <div class="list-group menu">
    $forall (category, products) <- rows
      <h4>#{categoryName category}

      $forall product <- products
        <p>#{productName product} - #{productPrice product}</p>

When I compile though I get the error message:

Handler/Menu.hs:11:7:
    Couldn't match type ‘[(Category, [Product])]’
                   with ‘(Category, t0 Product)’
    Expected type: ReaderT SqlBackend m1 (Category, t0 Product)
      Actual type: ReaderT SqlBackend m1 [(Category, [Product])]
    In the second argument of ‘Data.Foldable.mapM_’, namely ‘rows’
    In a stmt of a 'do' block:
      Data.Foldable.mapM_
        (\ (category_aiv7, products_aiv8)
           -> do { (asWidgetT GHC.Base.. toWidget)
                     ((blaze-markup-0.7.0.3:Text.Blaze.Internal.preEscapedText
                       GHC.Base.. Data.Text.pack)
                        "<div class=\"list-group-item\"><h4 class=\"list-group-item-heading\">");
                   (asWidgetT GHC.Base.. toWidget)
                     (toHtml (categoryName category_aiv7));
                   .... })
        rows

I don't understand why it is expecting this and what I can do to make it work. Many Thanks.

Update: My handler.

getMenuR :: Handler Html
getMenuR = do
  let rows = query

  defaultLayout $ do
    $(widgetFile "menu")

query = do
  cats <- selectList [] [Asc CategoryName]
  forM cats $ \(Entity catId cat) -> do
      products <- selectList
          [ProductCategory ==. catId]
          [Asc ProductName]
      return (cat, map entityVal products)
1
I think the problem is in your Haskell code. What does the code that created rows look like?Michael Snoyman
Hi Michael, It was the code that you helped with the other day. I have added it to the question. Thanks Again.Stewart Webb
The problem is using a let binding. You should use the slurp operator instead (<-).Michael Snoyman
Hi, so I changed from let rows = query to rows <- query and now I am getting this error: Handler/Menu.hs:8:11: Couldn't match expected type ‘HandlerT App IO (t0 (Category, t1 Product))’ with actual type ‘ReaderT SqlBackend m0 [(Category, [Product])]’ Stewart Webb
You need runDb. I'd recommend looking more closely as the Yesod/persistent examples in the bookMichael Snoyman

1 Answers

0
votes

After the help from Michael it is as easy as replacing let rows = query with rows <- runDB query