cultureamp / react-elm-components

Write React components in Elm
https://www.npmjs.com/package/react-elm-components
BSD 3-Clause "New" or "Revised" License
779 stars 54 forks source link

Uncaught TypeError: Cannot read property 'embed' of undefined #9

Closed heath closed 7 years ago

heath commented 7 years ago

The elm component fails to render. The error in the console is the title of this bug report.

To reproduce: 1.

git clone https://github.com/richardkall/react-starter.git

mkdir elm && touch elm/Counter.elm

Add the following into Counter.elm:

{- This file re-implements the Elm Counter example (1 counter) with elm-mdl
   buttons. Use this as a starting point for using elm-mdl components in your own
   app.
-}

module Counter exposing (..)

import Html exposing (..)
import Html.Attributes exposing (href, class, style)
import Material
import Material.Scheme
import Material.Button as Button
import Material.Options as Options exposing (css)

-- MODEL

type alias Model =
    { count : Int
    , mdl :
        Material.Model
        -- Boilerplate: model store for any and all Mdl components you use.
    }

model : Model
model =
    { count = 0
    , mdl =
        Material.model
        -- Boilerplate: Always use this initial Mdl model store.
    }

-- ACTION, UPDATE

type Msg
    = Increase
    | Reset
    | Mdl (Material.Msg Msg)

-- Boilerplate: Msg clause for internal Mdl messages.

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Increase ->
            ( { model | count = model.count + 1 }
            , Cmd.none
            )

        Reset ->
            ( { model | count = 0 }
            , Cmd.none
            )

        -- Boilerplate: Mdl action handler.
        Mdl msg_ ->
            Material.update Mdl msg_ model

-- VIEW

type alias Mdl =
    Material.Model

view : Model -> Html Msg
view model =
    div
        [ style [ ( "padding", "2rem" ) ] ]
        [ text ("Current count: " ++ toString model.count)
          {- We construct the instances of the Button component that we need, one
             for the increase button, one for the reset button. First, the increase
             button. The first three arguments are:

               - A Msg constructor (`Mdl`), lifting Mdl messages to the Msg type.
               - An instance id (the `[0]`). Every component that uses the same model
                 collection (model.mdl in this file) must have a distinct instance id.
               - A reference to the elm-mdl model collection (`model.mdl`).

             Notice that we do not have to add fields for the increase and reset buttons
             separately to our model; and we did not have to add to our update messages
             to handle their internal events.

             Mdl components are configured with `Options`, similar to `Html.Attributes`.
             The `Options.onClick Increase` option instructs the button to send the `Increase`
             message when clicked. The `css ...` option adds CSS styling to the button.
             See `Material.Options` for details on options.
          -}
        , Button.render Mdl
            [ 0 ]
            model.mdl
            [ Options.onClick Increase
            , css "margin" "0 24px"
            ]
            [ text "Increase" ]
        , Button.render Mdl
            [ 1 ]
            model.mdl
            [ Options.onClick Reset ]
            [ text "Reset" ]
        ]
        |> Material.Scheme.top

-- Load Google Mdl CSS. You'll likely want to do that not in code as we
-- do here, but rather in your master .html file. See the documentation
-- for the `Material` module for details.

main : Program Never Model Msg
main =
    Html.program
        { init = ( model, Cmd.none )
        , view = view
        , subscriptions = always Sub.none
        , update = update
        }

3.

Add this to elm/elm-package.json:

{
    "version": "1.0.0",
    "summary": "helpful summary of your project, less than 80 characters",
    "repository": "https://github.com/user/project.git",
    "license": "BSD3",
    "source-directories": [
        "."
    ],
    "exposed-modules": [],
    "dependencies": {
                "debois/elm-mdl": "8.1.0 <= v < 8.1.1",
        "elm-lang/core": "5.0.0 <= v < 6.0.0",
        "elm-lang/html": "2.0.0 <= v < 3.0.0"
    },
    "elm-version": "0.18.0 <= v < 0.19.0"
}

cd elm && elm-package install -y && elm-make Counter.elm --output Counter.js && cd ..

git apply diff.patch where diff.patch is this:

diff --git a/client/routes/About/index.js b/client/routes/About/index.js
index 2e90d21..2014569 100644
--- a/client/routes/About/index.js
+++ b/client/routes/About/index.js
@@ -1,12 +1,12 @@
 import React from 'react';

-import H1 from '../../components/H1';
+import Elm from 'react-elm-components'
+import { Counter } from '../../../elm/Counter'
+

 function About() {
   return (
-    <div>
-      <H1>About</H1>
-    </div>
+    <Elm src={ Counter }/>
   );
 }

diff --git a/package.json b/package.json
index 496c0d3..49306f0 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,7 @@
     "morgan": "1.8.1",
     "react": "15.4.2",
     "react-dom": "15.4.2",
+    "react-elm-components": "^1.0.1",
     "react-router-dom": "4.0.0-beta.8",
     "rimraf": "2.6.1",
     "styled-components": "2.0.0-7",```

6.

npm i && npm run build && npm run dev

7.

Visit http://localhost:3000, click on the About link, and the error should be in the console.

This doesn’t occur when using the counter example from http://guide.elm-lang.org/ It might have something to do with elm-mdl.

heath commented 7 years ago

These instructions weren't correct. The Elm component and the React component both had the same name, so the React component was trying to call embed on itself. Thanks @pholisma!