I am trying Yesod
book examples documented on Yesod webpage. One of the examples is for Chat application embedded in Wiki. When I try it in ghci (loading Chat
module from Wiki.hs
which contains Wiki example code), I get the error below for Chat.hs:
Chat.hs:122:34:
Could not deduce (Text.Julius.ToJavascript Text)
arising from a use of `Text.Julius.toJavascript'
from the context (YesodChat master)
bound by the type signature for
chatWidget :: YesodChat master =>
(Route Chat -> Route master) -> GWidget sub master ()
at Chat.hs:(81,15)-(83,35)
Possible fix:
add an instance declaration for (Text.Julius.ToJavascript Text)
In the first argument of `Text.Julius.Javascript', namely
`Text.Julius.toJavascript output'
In the expression:
Text.Julius.Javascript (Text.Julius.toJavascript output)
In the first argument of `Data.Monoid.mconcat', namely
`[Text.Julius.Javascript
((Data.Text.Lazy.Builder.fromText . Text.Shakespeare.pack')
"\
\// Set up the receiving end\
\var output = document.getElementById(\""),
Text.Julius.Javascript (Text.Julius.toJavascript output),
Text.Julius.Javascript
((Data.Text.Lazy.Builder.fromText . Text.Shakespeare.pack')
"\");\
\var src = new EventSource(\""),
Text.Julius.Javascript
(Data.Text.Lazy.Builder.fromText
(_render_a3Yr (toMaster ReceiveR) [])),
....]'
I am not very familiar with Yesod libraries yet. So, I am stumped by the above error - I have seen this error in other Yesod examples too where toWidget
function is called. So, it seems to be related to toWidget
function. I will appreciate help in fixing the above error.
I am using ghc 7.6.1
with yesod 1.1.4.1
.
Update:
Fixed following Hammar's suggestion. I made two changes in Chat.hs
.
Add import statement for rawJS:
import Text.Julius (rawJS)
Track down all instances of #{} blocks within julius whamlet
in Chat.hs
, and replace them with {# rawJS ...}
var output = document.getElementById("#{rawJS output}");
var input = document.getElementById("#{rawJS input}");
I don't have Yesod installed to test it at the moment, but according to this blog post you should just have to change #{output}
to #{rawJS output}
and so on when interpolating JavaScript identifiers.
In shakespeare-js-1.1.0
, the ToJavascript
instances for Text
and some other types have been removed:
-- | A typeclass for types that can be interpolated in CoffeeScript templates.
class ToJavascript a where
toJavascript :: a -> Builder
#if 0
instance ToJavascript [Char] where toJavascript = fromLazyText . TL.pack
instance ToJavascript TS.Text where toJavascript = fromText
instance ToJavascript TL.Text where toJavascript = fromLazyText
instance ToJavascript Javascript where toJavascript = unJavascript
instance ToJavascript Builder where toJavascript = id
#endif
instance ToJavascript Value where toJavascript = fromValue
while in previous versions of the package, they were only conditionally disabled:
#ifndef SAFER_INTERPOLATION
I don't know whether that's intentional and meant to remain so, or just a forgotten development change.
To use the example as is, you would need to rebuild yesod against shakespeare-js < 1.1
. That would mean uninstalling a lot of packages first, or a new sandbox (if you're using cabal-dev or some other sandboxing tool).
The only instances of ToJavascript
in shakespeare-js-1.1.0
are RawJavascript
(a newtype
wrapper around Builder
) and Value
(a type for JSON values) from the aeson
package.
You could just wrap output
in
Text.Julius.toJavascript output
in a RawJavascript . Data.Text.Lazy.Builder.fromText
to get a RawJavascript
value and make it work if it were real code, but since it's TH-generated, you'd need to fix the TH output or the quasiquoter - neither of which I know how to do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With