mirror of
https://github.com/aelve/guide.git
synced 2024-11-27 18:12:44 +03:00
parent
ac6ad91d34
commit
bb510a9f1d
@ -8,7 +8,7 @@ import Data.Maybe (Maybe(..))
|
||||
import Guide.Api.Types (CCategoryDetail, CUid)
|
||||
import Guide.CategoryDetail.Routes (Route(..))
|
||||
import Guide.CategoryDetail.State (State(..))
|
||||
import Guide.Common.Api (ApiError, getCategory)
|
||||
import Guide.Common.Api (EndpointError, getCategory)
|
||||
import Guide.Common.Types (AppEffects, CategoryName)
|
||||
import Network.RemoteData (RemoteData(..), isNotAsked)
|
||||
import Pux (EffModel, noEffects)
|
||||
@ -19,7 +19,7 @@ data Event
|
||||
| RequestCategory CategoryName (CUid String)
|
||||
-- TODO: ^ Use `CUid Category` instead of `CUid String` as second type parameter
|
||||
-- if we have found a way to bridge `Uid a` properly from `Haskell` to `PS`
|
||||
| ReceiveCategory (Either ApiError CCategoryDetail)
|
||||
| ReceiveCategory (Either EndpointError CCategoryDetail)
|
||||
|
||||
foldp :: ∀ fx. Event -> State -> EffModel State Event (AppEffects fx)
|
||||
|
||||
|
@ -5,14 +5,14 @@ import Data.Newtype (class Newtype)
|
||||
import Data.Show (class Show)
|
||||
import Guide.Api.Types (CCategoryDetail)
|
||||
import Guide.CategoryDetail.Routes (Route, match)
|
||||
import Guide.Common.Api (ApiError)
|
||||
import Guide.Common.Api (EndpointError)
|
||||
import Network.RemoteData (RemoteData(..))
|
||||
|
||||
newtype State = State
|
||||
{ title :: String
|
||||
, route :: Route
|
||||
, errors :: Array String
|
||||
, category :: RemoteData ApiError CCategoryDetail
|
||||
, category :: RemoteData EndpointError CCategoryDetail
|
||||
, loaded :: Boolean
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ init :: String -> State
|
||||
init url = State
|
||||
{ title: "CategoryDetail page" -- TODO (sectore): Change title
|
||||
, route: match url
|
||||
, errors: []
|
||||
, errors: []
|
||||
, category: NotAsked
|
||||
, loaded: false
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ import Prelude
|
||||
import Data.Array ((:))
|
||||
import Data.Either (Either(..))
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Guide.Common.Api (ApiError, getCategories)
|
||||
import Guide.CategoryOverview.Routes (Route(..))
|
||||
import Guide.CategoryOverview.State (State(..))
|
||||
import Guide.Common.Api (EndpointError, getCategories)
|
||||
import Guide.Common.Types (AppEffects, CategoryName, CCategories)
|
||||
import Network.RemoteData (RemoteData(..), isNotAsked)
|
||||
import Pux (EffModel, noEffects)
|
||||
@ -16,13 +16,13 @@ data Event =
|
||||
PageView Route
|
||||
-- API
|
||||
| GetCategories CategoryName
|
||||
| ReceiveCategories (Either ApiError CCategories)
|
||||
| ReceiveCategories (Either EndpointError CCategories)
|
||||
|
||||
foldp :: forall eff. Event -> State -> EffModel State Event (AppEffects eff)
|
||||
|
||||
foldp (GetCategories catName) (State st) =
|
||||
{ state: State $ st { categories = Loading
|
||||
}
|
||||
foldp (GetCategories catName) (State state) =
|
||||
{ state: State $ state { categories = Loading
|
||||
}
|
||||
, effects:
|
||||
[ getCategories catName >>= pure <<< Just <<< ReceiveCategories
|
||||
]
|
||||
|
@ -3,8 +3,8 @@ module Guide.CategoryOverview.State where
|
||||
import Data.Generic (class Generic, gShow)
|
||||
import Data.Newtype (class Newtype)
|
||||
import Data.Show (class Show)
|
||||
import Guide.Common.Api (ApiError)
|
||||
import Guide.CategoryOverview.Routes (Route, match)
|
||||
import Guide.Common.Api (EndpointError)
|
||||
import Guide.Common.Types (CategoryName(..), CCategories)
|
||||
import Network.RemoteData (RemoteData(..))
|
||||
|
||||
@ -13,7 +13,7 @@ newtype State = State
|
||||
, route :: Route
|
||||
, loaded :: Boolean
|
||||
, errors :: Array String
|
||||
, categories :: RemoteData ApiError CCategories
|
||||
, categories :: RemoteData EndpointError CCategories
|
||||
, categoryName :: CategoryName
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ import Guide.Common.Types (CCategories)
|
||||
import Network.RemoteData (RemoteData(..))
|
||||
import Pux.DOM.HTML (HTML) as P
|
||||
import Pux.DOM.HTML.Attributes (key) as P
|
||||
import Text.Smolder.HTML (div, h1, h2, a, ul, li) as S
|
||||
import Text.Smolder.HTML (div, h1, a, ul, li) as S
|
||||
import Text.Smolder.HTML.Attributes (href) as S
|
||||
import Text.Smolder.Markup ((!))
|
||||
import Text.Smolder.Markup (text) as S
|
||||
|
@ -3,12 +3,13 @@ module Guide.Common.Api where
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.Aff (Aff)
|
||||
import Data.Argonaut.Generic.Aeson (options)
|
||||
import Data.Argonaut.Generic.Decode (genericDecodeJson)
|
||||
import Data.Argonaut.Generic.Aeson (userDecoding, userEncoding)
|
||||
import Data.Argonaut.Generic.Decode (Options(..), SumEncoding(..), genericDecodeJson)
|
||||
import Data.Argonaut.Generic.Util (stripModulePath)
|
||||
import Data.Bifunctor (bimap)
|
||||
import Data.Either (Either(..), either)
|
||||
import Data.Foreign (Foreign, unsafeFromForeign)
|
||||
import Data.Generic (class Generic, gShow)
|
||||
import Data.Newtype (class Newtype)
|
||||
import Data.Generic (class Generic)
|
||||
import Guide.Api.Types (CCategoryDetail, CUid(..))
|
||||
import Guide.Common.Types (CCategories, CategoryName)
|
||||
import IsomorphicFetch (FETCH, get, json)
|
||||
@ -16,29 +17,57 @@ import IsomorphicFetch (FETCH, get, json)
|
||||
endpoint :: String
|
||||
endpoint = "http://localhost:4400"
|
||||
|
||||
-- TODO (sectore): Provide more API errors
|
||||
-- such as
|
||||
-- data ApiError
|
||||
-- = StatusError String
|
||||
-- | JSONError String
|
||||
-- | ServerError B.ApiError
|
||||
newtype ApiError = ApiError String
|
||||
derive instance gApiError :: Generic ApiError
|
||||
derive instance ntApiError :: Newtype ApiError _
|
||||
instance sApiError :: Show ApiError where
|
||||
show = gShow
|
||||
data EndpointError
|
||||
= JSONDecodingError String
|
||||
| ServerError String
|
||||
|
||||
derive instance gEndpointError :: Generic EndpointError
|
||||
|
||||
instance showEndpointError :: Show EndpointError where
|
||||
show (JSONDecodingError e) =
|
||||
"[JSONDecodingError]: " <> show e
|
||||
show (ServerError e) =
|
||||
"[ServerError]: " <> show e
|
||||
|
||||
-- custom encode options (because `unpackRecords` should be `false`)
|
||||
sumEncoding :: SumEncoding
|
||||
sumEncoding = TaggedObject
|
||||
{ tagFieldName: "tag"
|
||||
, contentsFieldName: "contents"
|
||||
, unpackRecords: false
|
||||
}
|
||||
|
||||
options :: Options
|
||||
options = Options
|
||||
{ constructorTagModifier: stripModulePath
|
||||
, allNullaryToStringTag: true
|
||||
, sumEncoding
|
||||
, flattenContentsArray: true
|
||||
, encodeSingleConstructors: false
|
||||
, userEncoding
|
||||
, userDecoding
|
||||
, fieldLabelModifier: id
|
||||
, omitNothingFields: false
|
||||
}
|
||||
|
||||
-- | Decoder for json data
|
||||
decodeJson :: forall a. (Generic a) => Foreign -> Either String a
|
||||
decodeJson = genericDecodeJson options <<< unsafeFromForeign
|
||||
|
||||
getCategories :: forall eff. CategoryName -> Aff (fetch :: FETCH | eff) (Either ApiError CCategories)
|
||||
-- | Decodes a result considering JSON and Server errors
|
||||
decodeResult :: forall a. Generic a => Foreign -> Either EndpointError a
|
||||
decodeResult = either (Left <<< JSONDecodingError) (bimap ServerError id) <<< decodeJson
|
||||
|
||||
-- | Fetches all categories
|
||||
getCategories :: forall eff. CategoryName -> Aff (fetch :: FETCH | eff) (Either EndpointError CCategories)
|
||||
getCategories _ = do
|
||||
response <- get $ endpoint <> "/categories"
|
||||
json' <- json response
|
||||
pure $ either (Left <<< ApiError) pure $ decodeJson json'
|
||||
pure $ decodeResult json'
|
||||
|
||||
getCategory :: forall eff. CategoryName -> (CUid String) -> Aff (fetch :: FETCH | eff) (Either ApiError CCategoryDetail)
|
||||
-- | Fetches a categories by a given category id
|
||||
getCategory :: forall eff. CategoryName -> (CUid String) -> Aff (fetch :: FETCH | eff) (Either EndpointError CCategoryDetail)
|
||||
getCategory _ (CUid catId) = do
|
||||
response <- get $ endpoint <> "/category/" <> catId
|
||||
json' <- json response
|
||||
pure $ either (Left <<< ApiError) pure $ decodeJson json'
|
||||
pure $ decodeResult json'
|
||||
|
Loading…
Reference in New Issue
Block a user