haskellyesodyesod-forms

How should I create a selectFieldList with using runDB function to fetch values?


I would like to add a selectionFieldList to my Form, but unfortunetlly I could not fill with values from DB beacuse I got compile error.

I have form definition like this:

flowerForm = renderDivs $ FormFlower
<$> areq textField "Flower" Nothing
<*> areq (selectFieldList findAllAsTuple) "Category" Nothing

And the findAllAsTuple function :

findAllAsTuple ::[(Text,Text)]
findAllAsTuple = fmap (map (\cat -> (categoryName $ entityVal cat, categoryName $ entityVal cat))) $ runDB $ selectList [] [Asc CategoryName]

But I got this error:

Handler\Category.hs:6:18:
Couldn't match type `HandlerT site0 IO' with `[]'
Expected type: [(Text, Text)]
  Actual type: HandlerT site0 IO [(Text, Text)]
In the expression:
  fmap
    (map
       (\ cat
          -> (categoryName $ entityVal cat, categoryName $ entityVal cat)))
  $ runDB $ selectList [] [Asc CategoryName]
In an equation for `findAllAsTuple':
    findAllAsTuple
      = fmap
          (map
             (\ cat
                -> (categoryName $ entityVal cat, categoryName $ entityVal cat)))
        $ runDB $ selectList [] [Asc CategoryName]

If I delete the fmap I got this error:

Handler\Category.hs:6:95:
Couldn't match expected type `[Entity Category]'
            with actual type `HandlerT site0 IO [Entity Category]'
In the second argument of `($)', namely
  `runDB $ selectList [] [Asc CategoryName]'
In the expression:
  map
    (\ cat
       -> (categoryName $ entityVal cat, categoryName $ entityVal cat))
  $ runDB $ selectList [] [Asc CategoryName]
In an equation for `findAllAsTuple':
    findAllAsTuple
      = map
          (\ cat
             -> (categoryName $ entityVal cat, categoryName $ entityVal cat))
        $ runDB $ selectList [] [Asc CategoryName]

I tried this way as well :

findAllAsTuple ::[(Text,Text)]
findAllAsTuple = do
            items <-  runDB $ selectList [] [Asc CategoryName]
            return $ map (\cat -> (categoryName $ entityVal cat,      categoryName $ entityVal cat))  items

But I then got this :

Handler\Category.hs:8:17:
Couldn't match type `[(Text, Text)]' with `(Text, Text)'
Expected type: [(Text, Text)]
  Actual type: [[(Text, Text)]]
In a stmt of a 'do' block:
  return
  $ map
      (\ cat
         -> (categoryName $ entityVal cat, categoryName $ entityVal cat))
      items
In the expression:
  do { items <- runDB $ selectList [] [Asc CategoryName];
       return
       $ map
           (\ cat
              -> (categoryName $ entityVal cat, categoryName $ entityVal cat))
           items }
In an equation for `findAllAsTuple':
    findAllAsTuple
      = do { items <- runDB $ selectList [] [Asc CategoryName];
             return
             $ map
                 (\ cat
                    -> (categoryName $ entityVal cat, categoryName $ entityVal cat))
                 items }

I do not understand why. If I write a simple map function like this :

 findAllAsTuple ::[(Text,Text)]
 findAllAsTuple =  map (\cat -> (cat,cat))  ["red","blue","yellow"]

It is work well and I do not get any type error.


Solution

  • Finally I found the solution.

    My function should look like this :

    findAllAsTuple :: HandlerT App IO (OptionList Text)
    findAllAsTuple =do 
                 items <- runDB $ selectList [] [Asc CategoryName] 
                 optionsPairs $ map (\c -> (categoryName $ entityVal    c,categoryName $ entityVal c)) items
    

    Dmitry was right I should use selectField instead of selectFieldList.

    The optionsPairs will create the OptionList from result. This question was duplicated : Capturing Persistent Relations in a Form