Could not deduce (IHP.RouterSupport.AutoRoute (Id' "hardwareVendors"))

120 Views Asked by At

It looks like I'm not passing the correct parameter to this action. I'm not sure how to debug this error though :/ Any tips on getting started?

error:

Web/View/HardwareVendors/Show.hs:8:33
    • Could not deduce (IHP.RouterSupport.AutoRoute
                          (Id' "hardwareVendors"))
        arising from a use of ‘IHP.HSX.QQ.applyAttribute’
      from the context: (?context::ControllerContext, ?view::ShowView)
        bound by the type signature for:
                   html :: (?context::ControllerContext, ?view::ShowView) =>
                           ShowView -> Text.Blaze.Html.Html
        at Web/View/HardwareVendors/Show.hs:8:5-8
    • In the expression:
        ((IHP.HSX.QQ.applyAttribute
            ((Data.Text.unpackCStringLen# "id"#) 2))
           ((Data.Text.unpackCStringLen# " id=\""#) 5))
          ((get #id) hardwareVendor)
      In the second argument of ‘IHP.HSX.QQ.applyAttributes’, namely
        ‘[\ h_aArT
            -> (h_aArT
                  ! ((Text.Blaze.Internal.attribute
                        (Text.Blaze.Internal.textTag
                           ((Data.Text.unpackCStringLen# "type"#) 4)))
                       (Text.Blaze.Internal.textTag
                          ((Data.Text.unpackCStringLen# " type=\""#) 7)))
                      (preEscapedTextValue ((Data.Text.unpackCStringLen# "hidden"#) 6))),
          \ h_aArU
            -> (h_aArU
                  ! ((Text.Blaze.Internal.attribute
                        (Text.Blaze.Internal.textTag
                           ((Data.Text.unpackCStringLen# "name"#) 4)))
                       (Text.Blaze.Internal.textTag
                          ((Data.Text.unpackCStringLen# " name=\""#) 7)))
                      (preEscapedTextValue
                         ((Data.Text.unpackCStringLen# "hardwareVendorId"#) 16))),
          ((IHP.HSX.QQ.applyAttribute
              ((Data.Text.unpackCStringLen# "id"#) 2))
             ((Data.Text.unpackCStringLen# " id=\""#) 5))
            ((get #id) hardwareVendor),
          \ h_aArV
            -> (h_aArV
                  ! ((Text.Blaze.Internal.attribute
                        (Text.Blaze.Internal.textTag
                           ((Data.Text.unpackCStringLen# "class"#) 5)))
                       (Text.Blaze.Internal.textTag
                          ((Data.Text.unpackCStringLen# " class=\""#) 8)))
                      (preEscapedTextValue
                         ((Data.Text.unpackCStringLen# "form-control"#) 12)))]’
      In the expression:
        (IHP.HSX.QQ.applyAttributes
           ((((Text.Blaze.Internal.Leaf
                 (IHP.HSX.QQ.textToStaticString
                    ((Data.Text.unpackCStringLen# "input"#) 5)))
                (IHP.HSX.QQ.textToStaticString
                   ((Data.Text.unpackCStringLen# "<input"#) 6)))
               (IHP.HSX.QQ.textToStaticString
                  ((Data.Text.unpackCStringLen# ">"#) 1)))
              ()))
          [\ h_aArT
             -> (h_aArT
                   ! ((Text.Blaze.Internal.attribute
                         (Text.Blaze.Internal.textTag
                            ((Data.Text.unpackCStringLen# "type"#) 4)))
                        (Text.Blaze.Internal.textTag
                           ((Data.Text.unpackCStringLen# " type=\""#) 7)))
                       (preEscapedTextValue ((Data.Text.unpackCStringLen# "hidden"#) 6))),
           \ h_aArU
             -> (h_aArU
                   ! ((Text.Blaze.Internal.attribute
                         (Text.Blaze.Internal.textTag
                            ((Data.Text.unpackCStringLen# "name"#) 4)))
                        (Text.Blaze.Internal.textTag
                           ((Data.Text.unpackCStringLen# " name=\""#) 7)))
                       (preEscapedTextValue
                          ((Data.Text.unpackCStringLen# "hardwareVendorId"#) 16))),
           ((IHP.HSX.QQ.applyAttribute
               ((Data.Text.unpackCStringLen# "id"#) 2))
              ((Data.Text.unpackCStringLen# " id=\""#) 5))
             ((get #id) hardwareVendor),
           \ h_aArV
             -> (h_aArV
                   ! ((Text.Blaze.Internal.attribute
                         (Text.Blaze.Internal.textTag
                            ((Data.Text.unpackCStringLen# "class"#) 5)))
                        (Text.Blaze.Internal.textTag
                           ((Data.Text.unpackCStringLen# " class=\""#) 8)))
                       (preEscapedTextValue
                          ((Data.Text.unpackCStringLen# "form-control"#) 12)))]
  |
8 |     html ShowView { .. } = [hsx|
  |                                 ^...
 
<interactive>:47:37
    Variable not in scope: app :: Async a0
    Suggested fix:
      Perhaps use ‘ClassyPrelude.ap’ (imported from ClassyPrelude)

./Controller/HardwareVendor.hs

module Web.Controller.HardwareVendors where

import Web.Controller.Prelude
import Web.View.HardwareVendors.Index
import Web.View.HardwareVendors.Show
import Web.View.HardwareVendors.ShowResponse

instance Controller HardwareVendorsController where
    action HardwareVendorsAction = do
        hardwareVendors <- query @HardwareVendor |> fetch
        render IndexView { .. }

    action ShowHardwareVendorAction { hardwareVendorId } = do
        hardwareVendor <- fetch hardwareVendorId
        render ShowView { .. }

    action ShowHardwareVendorResponseAction { hardwareVendorId } = do
        hardwareVendor <- fetch hardwareVendorId
        render ShowResponseView { .. }
-- View/HardwareVendors/Show.hs

module Web.View.HardwareVendors.Show where
import Data.Text as Text
import Web.View.Prelude

data ShowView = ShowView { hardwareVendor :: HardwareVendor }

instance View ShowView where
    html ShowView { .. } = [hsx|
    <form id="select-vendor-form" action="/ShowHardwareVendorResponse" method="get">
      {renderInputs hardwareVendor}
      <input type="hidden" type="text" name="hardwareVendorId" value={get #id HardwareVendor} class="form-control" />
      <input type="submit" value="Submit">
    </form>

|]
renderInputs :: HardwareVendor -> Html
renderInputs vendor = [hsx|
        {forEach (requiredfields vendor) renderInput}
|]

renderInput :: Text -> Html
renderInput field = [hsx|
      <label for={field}>{field}</label>
      <input type="text" name={field} id={field} class="form-control" />
|]

Web/Types.hs:

module Web.Types where

import IHP.Prelude
import IHP.ModelSupport
import Generated.Types

data WebApplication = WebApplication deriving (Eq, Show)

data HardwareVendorsController
    = HardwareVendorsAction
    | ShowHardwareVendorAction { hardwareVendorId :: !(Id HardwareVendor) }
    | ShowHardwareVendorResponseAction { hardwareVendorId :: !(Id HardwareVendor) }
    deriving (Eq, Show, Data)

related issue: https://ihp.digitallyinduced.com/community/ShowThread?threadId=ad73d6a5-2481-4e2f-af46-9bf8849f998b

silly stackoverflow validation. silly stackoverflow validation. silly stackoverflow validation. silly stackoverflow validation. silly stackoverflow validation. silly stackoverflow validation. silly stackoverflow validation. silly stackoverflow validation.

1

There are 1 best solutions below

2
On BEST ANSWER

In your View File: View/HardwareVendors/Show.hs

Change value={get #id HardwareVendor} To: value={inputValue (get #id HardwareVendor)} Notice the inputValue function call, it gives us the raw UUID value.

What happens when using get #id HardwareVendor in a View file, is the router will try to find the correct path to HardwareVendor id, but in this case there is no route setup for it. That's where the (IHP.RouterSupport.AutoRoute) error arises.

With inputValue we force it to give us a raw value, the UUID, instead of trying to create a routing path.

Related IHP Github Issue: https://github.com/digitallyinduced/ihp/issues/1013