mdietz
mdietz

Reputation: 53

Yesod Mongo DB and JSON

I am trying to query a MongoDB instance to return a Point. Basically a placeholder for now, just a basic datatype as I am trying to learn Yesod. Below is my route for the Handler. How does one query a database by id (or some other filter) and return the information as JSON?

{-# LANGUAGE EmptyDataDecls    #-}
{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE GADTs             #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE TypeFamilies      #-}
{-# LANGUAGE RecordWildCards   #-}
{-# LANGUAGE DeriveGeneric     #-}

module Handler.Points where

import Import

mkPersist sqlSettings [persistLowerCase|
Point
    name String
    deriving Show
|]

$(deriveToJSON defaultOptions ''PointGeneric)

getPointsR :: String -> Handler Value
getPointsR pId = do
    pts <- runDB $ selectList [PointName ==. pId] []
    returnJson (pts :: [Entity Point])

And this is the error message I am getting.

Handler\Points.hs:25:20:
    Couldn't match type `Database.Persist.MongoDB.MongoBackend'
                   with `persistent-1.2.3.0:Database.Persist.Sql.Types.SqlBackend'
    In the second argument of `($)', namely
      `selectList [PointName ==. pId] []'
    In a stmt of a 'do' block:
      pts <- runDB $ selectList [PointName ==. pId] []
    In the expression:
      do { pts <- runDB $ selectList [PointName ==. pId] [];
           returnJson (pts :: [Entity Point]) }
Build failure, pausing...

Upvotes: 2

Views: 465

Answers (2)

mdietz
mdietz

Reputation: 53

I figured it out. I was using the scaffolded setup, and to add the model I should have put it in the config/models file. mongoSettings is local to the Model.hs file, while sqlSettings made the compiler think I was trying to use a SQL resource instead of the Mongo DB.

Upvotes: 0

Michael Snoyman
Michael Snoyman

Reputation: 31335

returnJson expects to be provided a pure value, but you've provided an action that generates a pure value. You can use do-notation to slurp out the pure value and then use returnJson:

do
    x <- runDB $ selectFirst [ PointId ==. pId ] []
    returnJson x

Alternatively, you could use the monadic bind operator (which do-notation is simply sugar for):

runDB (selectFirst [PointId ==. pId] []) >>= returnJson

This may reveal other problems, but you should at least get a different error message after this step.

Upvotes: 2

Related Questions