Compare commits
37 Commits
solutions
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
673b5d5eed | ||
|
|
dfe4cc02d9 | ||
|
|
331813a90b | ||
|
|
f6d6dc5ffc | ||
|
|
c1401c637f | ||
|
|
d5d25f90f6 | ||
|
|
98901d3743 | ||
|
|
c9287a157c | ||
|
|
b2089add0d | ||
|
|
04ed226507 | ||
|
|
da827954e5 | ||
|
|
965184ca09 | ||
|
|
1bcb581666 | ||
|
|
b5697d0765 | ||
|
|
e5124265f8 | ||
|
|
81b51ab973 | ||
|
|
3c6e9aeb07 | ||
|
|
6142e8d685 | ||
|
|
b2b9cc5b76 | ||
|
|
ab31fd08c0 | ||
|
|
3f9b3381c2 | ||
|
|
af7ed944f1 | ||
|
|
4035369af2 | ||
|
|
850d4e6ff0 | ||
|
|
5b9cdfb3b3 | ||
|
|
2bd5aa8141 | ||
|
|
0a9fadcf87 | ||
|
|
4fcaad042a | ||
|
|
bb38d331b4 | ||
|
|
0efe239ae4 | ||
|
|
69f3c478fb | ||
|
|
0288b3fcb7 | ||
|
|
33713b59b8 | ||
|
|
6c04669ec5 | ||
|
|
50aa6ee0d6 | ||
|
|
e7b7d0bdc3 | ||
|
|
9288011f22 |
12
README.md
12
README.md
@@ -1,4 +1,4 @@
|
||||
<i>This workshop is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>. The `server/` directories use [`moleculer-node-realworld-example`](https://github.com/gothinkster/moleculer-node-realworld-example-app), which has its own license. The JavaScript interop example uses [`localForage`](https://github.com/localForage/localForage), which is (c) 2013-2017 Mozilla, under the Apache License 2.0. The rest of the code is a variation on [`elm-spa-example`](https://github.com/rtfeldman/elm-spa-example/), an [MIT-licensed](https://github.com/rtfeldman/elm-spa-example/blob/master/LICENSE) implementation of the [`realworld`](https://github.com/gothinkster/realworld) front-end. Many thanks to the authors of these projects!</i>
|
||||
<i>This workshop, as well as the slides that go with it (linked below), are all licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>. The `server/` directories use [`moleculer-node-realworld-example`](https://github.com/gothinkster/moleculer-node-realworld-example-app), which has its own license. The JavaScript interop example uses [`localForage`](https://github.com/localForage/localForage), which is (c) 2013-2017 Mozilla, under the Apache License 2.0. The rest of the code is a variation on [`elm-spa-example`](https://github.com/rtfeldman/elm-spa-example/), an [MIT-licensed](https://github.com/rtfeldman/elm-spa-example/blob/master/LICENSE) implementation of the [`realworld`](https://github.com/gothinkster/realworld) front-end. Many thanks to the authors of these projects!</i>
|
||||
|
||||
Getting Started
|
||||
===============
|
||||
@@ -14,7 +14,7 @@ Getting Started
|
||||
> **Note:** Make sure not to run this command with `sudo`! If it gives you an `EACCESS` error, apply [**this fix**](https://docs.npmjs.com/getting-started/fixing-npm-permissions#option-two-change-npms-default-directory) and then re-run the command (still without `sudo`).
|
||||
|
||||
```shell
|
||||
npm install -g elm-test@beta elm-format@rc
|
||||
npm install -g elm elm-test elm-format
|
||||
```
|
||||
|
||||
5. Clone this repository
|
||||
@@ -27,3 +27,11 @@ cd elm-0.19-workshop
|
||||
```
|
||||
|
||||
6. Continue with either the [`intro`](https://github.com/rtfeldman/elm-0.19-workshop/blob/master/intro/README.md) or [`advanced`](https://github.com/rtfeldman/elm-0.19-workshop/blob/master/advanced/README.md) instructions, depending on which workshop you're doing!
|
||||
|
||||
Video Course of this Workshop
|
||||
=============================
|
||||
|
||||
I recorded full-length videos for [Frontend Masters](https://frontendmasters.com/), in which I teach both of these workshops start to finish:
|
||||
|
||||
* [Introduction to Elm](https://frontendmasters.com/courses/intro-elm/) video course ([slides](https://docs.google.com/presentation/d/1LM_W2BRs_ItT-SPDe70C10cbwhGNHGQlJ1fVnAdnRIY/edit?usp=sharing)
|
||||
* [Advanced Elm](https://frontendmasters.com/courses/advanced-elm/) video course ([slides](https://docs.google.com/presentation/d/1aFZBXs9kzlZww2JN6iDmrYiQaxKlCAz6a5zpt882GHk/edit?usp=sharing))
|
||||
|
||||
@@ -15,7 +15,7 @@ some info about it that may be helpful in teaching this workshop.
|
||||
|
||||
## Slides
|
||||
|
||||
The [slides](https://docs.google.com/presentation/d/1sNx5k3_fHwJcgm9QEY1LsMH_TyF5SnnOSDKb8HvFsEU/edit?usp=sharing)
|
||||
The [slides](https://docs.google.com/presentation/d/1LM_W2BRs_ItT-SPDe70C10cbwhGNHGQlJ1fVnAdnRIY/edit?usp=sharing)
|
||||
I use with the workshop include speaker notes. If you’ve seen me give this
|
||||
workshop before, you may notice that I’m not following these notes very closely.
|
||||
|
||||
|
||||
@@ -43,7 +43,12 @@ If things aren’t working, the instructor will be happy to help!
|
||||
|
||||
## Links
|
||||
|
||||
* [Elm in Action](https://www.manning.com/books/elm-in-action?a_aid=elm_in_action&a_bid=b15edc5c), a book by [Richard Feldman](https://twitter.com/rtfeldman), creator of this workshop
|
||||
* [Official Elm Guide](https://guide.elm-lang.org/) by [Evan Czaplicki](https://twitter.com/czaplic), creator of Elm
|
||||
* [Elm Slack](http://elmlang.herokuapp.com/) - amazingly helpful chat community. People in [the `#beginners` channel](https://elmlang.slack.com/messages/C192T0Q1E/) are happy to answer questions!
|
||||
* [Elm Discourse](https://discourse.elm-lang.org/) - for longer-form discussions.
|
||||
* [The solutions to these exercises](https://github.com/rtfeldman/elm-0.19-workshop/tree/solutions/advanced)
|
||||
* [Slides for the Frontend Masters workshop that goes with this repo](https://docs.google.com/presentation/d/1aFZBXs9kzlZww2JN6iDmrYiQaxKlCAz6a5zpt882GHk/edit?usp=sharing)
|
||||
* [Advanced Elm Video Course](https://frontendmasters.com/courses/advanced-elm/) that goes with this repo
|
||||
* [The Life of a File](https://www.youtube.com/watch?v=XpDsk374LDE) - Evan Czaplicki
|
||||
* [The Importance of Ports](https://www.youtube.com/watch?v=P3pL85n9_5s) - Murphy Randle
|
||||
* [Working with Maybe](https://www.youtube.com/watch?v=43eM4kNbb6c) - Joël Quenneville
|
||||
* [Making Impossible States Impossible](https://www.youtube.com/watch?v=IcgmSRJHu_8) - Richard Feldman
|
||||
* [Scaling Elm Apps](https://www.youtube.com/watch?v=DoA4Txr4GUs) - Richard Feldman
|
||||
* [Make Data Structures](https://www.youtube.com/watch?v=x1FU3e0sT1I) - Richard Feldman
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -12,13 +12,14 @@ import Username exposing (Username)
|
||||
|
||||
|
||||
type alias Cred =
|
||||
-- 👉 TODO make Cred an opaque type, then fix the resulting compiler errors.
|
||||
-- Afterwards, it should no longer be possible for any other module to access
|
||||
-- this `token` vale directly!
|
||||
--
|
||||
-- 💡 HINT: Other modules still depend on being able to access the
|
||||
-- `username` value. Expand this module's API to expose a new way for them
|
||||
-- to access the `username` without also giving them access to `token`.
|
||||
{- 👉 TODO: Make Cred an opaque type, then fix the resulting compiler errors.
|
||||
Afterwards, it should no longer be possible for any other module to access
|
||||
this `token` value directly!
|
||||
|
||||
💡 HINT: Other modules still depend on being able to access the
|
||||
`username` value. Expand this module's API to expose a new way for them
|
||||
to access the `username` without also giving them access to `token`.
|
||||
-}
|
||||
{ username : Username
|
||||
, token : String
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -77,8 +77,8 @@ init session slug =
|
||||
|
||||
Relevant docs:
|
||||
|
||||
https://alpha.elm-lang.org/packages/elm/core/latest/Task#attempt
|
||||
https://alpha.elm-lang.org/packages/elm/core/latest/Task#perform
|
||||
https://package.elm-lang.org/packages/elm/core/latest/Task#attempt
|
||||
https://package.elm-lang.org/packages/elm/core/latest/Task#perform
|
||||
-}
|
||||
[ Article.fetch maybeCred slug
|
||||
|> Http.toTask
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"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": {
|
||||
"elm-lang/core": "5.1.1 <= v < 6.0.0",
|
||||
"elm-lang/html": "2.0.0 <= v < 3.0.0"
|
||||
},
|
||||
"elm-version": "0.18.0 <= v < 0.19.0"
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"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": {
|
||||
"elm-lang/core": "5.1.1 <= v < 6.0.0",
|
||||
"elm-lang/html": "2.0.0 <= v < 3.0.0"
|
||||
},
|
||||
"elm-version": "0.18.0 <= v < 0.19.0"
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1",
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0",
|
||||
"rtfeldman/elm-validate": "4.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
|
||||
3150
advanced/server/package-lock.json
generated
3150
advanced/server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
Introduction to Elm Workshop
|
||||
============================
|
||||
|
||||
If you haven't already, follow the [Getting Started instructions](https://github.com/rtfeldman/elm-0.19-workshop/blob/master/intro/README.md
|
||||
If you haven't already, follow the [Getting Started instructions](https://github.com/rtfeldman/elm-0.19-workshop#getting-started
|
||||
) at the root of this repository, then continue here!
|
||||
|
||||
## Start the server
|
||||
@@ -24,7 +24,7 @@ of the workshop, so **don't close it** until the workshop is over!
|
||||
|
||||
Leave the existing terminal running, and open a **second** terminal.
|
||||
|
||||
In the new termnal, `cd` into the `elm-0.19-workshop/intro/server/` directory again.
|
||||
In the new terminal, `cd` into the `elm-0.19-workshop/intro/server/` directory again.
|
||||
|
||||
Then run this to build the Elm code for the first time:
|
||||
|
||||
@@ -43,6 +43,9 @@ If things aren’t working, the instructor will be happy to help!
|
||||
|
||||
## Links
|
||||
|
||||
* [The solutions to these exercises](https://github.com/rtfeldman/elm-0.19-workshop/tree/solutions/intro)
|
||||
* [Slides for the Frontend Masters video course that goes with this repo](https://docs.google.com/presentation/d/1LM_W2BRs_ItT-SPDe70C10cbwhGNHGQlJ1fVnAdnRIY/edit?usp=sharing)
|
||||
* [Introduction to Elm Video Course](https://frontendmasters.com/courses/intro-elm/) that goes along with this repo.
|
||||
* [Elm in Action](https://www.manning.com/books/elm-in-action?a_aid=elm_in_action&a_bid=b15edc5c), a book by [Richard Feldman](https://twitter.com/rtfeldman), creator of this workshop
|
||||
* [Official Elm Guide](https://guide.elm-lang.org/) by [Evan Czaplicki](https://twitter.com/czaplic), creator of Elm
|
||||
* [Elm Slack](http://elmlang.herokuapp.com/) - amazingly helpful chat community. People in [the `#beginners` channel](https://elmlang.slack.com/messages/C192T0Q1E/) are happy to answer questions!
|
||||
|
||||
@@ -17,7 +17,7 @@ banner =
|
||||
</div>
|
||||
</div>
|
||||
|
||||
💡 HINT 1: the <div class="row"> above is an element with 2 child nodes.
|
||||
💡 HINT 1: the <div class="container"> above is an element with 2 child nodes.
|
||||
|
||||
💡 HINT 2: the <div class="feed-toggle"> below is an element with text.
|
||||
-}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"source-directories": [
|
||||
"."
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"elm/core": "1.0.0",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"elm/core": "1.0.0",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"elm/core": "1.0.0",
|
||||
@@ -19,4 +19,4 @@
|
||||
"direct": {},
|
||||
"indirect": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
module Main exposing (main)
|
||||
|
||||
-- NOTE: Make sure to follow the instructions in the README for part3
|
||||
-- to install the elm/browser package before running elm make!
|
||||
--
|
||||
-- FYI: 👇 You can see our new `Article` module in `src/Article.elm`
|
||||
|
||||
import Article
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"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": {
|
||||
"elm-lang/core": "5.1.1 <= v < 6.0.0",
|
||||
"elm-lang/html": "2.0.0 <= v < 3.0.0"
|
||||
},
|
||||
"elm-version": "0.18.0 <= v < 0.19.0"
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"elm/browser": "1.0.0",
|
||||
@@ -21,4 +21,4 @@
|
||||
"direct": {},
|
||||
"indirect": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ view model =
|
||||
]
|
||||
|
||||
|
||||
{-| 👉 TODO: Replace this comment with a type annotation for `view`
|
||||
{-| 👉 TODO: Replace this comment with a type annotation for `viewArticle`
|
||||
-}
|
||||
viewArticle article =
|
||||
div [ class "article-preview" ]
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -566,7 +566,7 @@ toTagList tagString =
|
||||
will result in an error! If it has been fixed, saving will work and the
|
||||
tags will be accepted.
|
||||
|
||||
💡 HINT: Here's how to remove all the "foo" strings from a list of strings:
|
||||
💡 HINT: Here's how to keep only the "foo" strings in a list of strings:
|
||||
|
||||
List.filter (\str -> str == "foo") listOfStrings
|
||||
-}
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -12,6 +12,6 @@ Then open `http://localhost:3000` in your browser.
|
||||
|
||||
## Exercise
|
||||
|
||||
We need to make login work. Currently it doesn't actually send a HTTP request to the server.
|
||||
We need to make signup work again. Currently it doesn't actually send a HTTP request to the server.
|
||||
|
||||
We'll fix this by editing `src/Page/Login.elm` and resolving the TODOs there.
|
||||
We'll fix this by editing `src/Page/Register.elm` and resolving the TODOs there.
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -168,7 +168,7 @@ update msg model =
|
||||
-}
|
||||
request : Http.Request Viewer
|
||||
request =
|
||||
Debug.todo "Call Http.post to represent a POST to /api/users/login"
|
||||
Debug.todo "Call Http.post to represent a POST to /api/users"
|
||||
|
||||
{- 👉 TODO: Use Http.send to turn the request we just defined
|
||||
into a Cmd for `update` to execute.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Part 8
|
||||
# Part 9
|
||||
|
||||
Once again, we'll be building `src/Main.elm`, but editing a different file.
|
||||
|
||||
To build everything, `cd` into the `part8/` directory and run8
|
||||
To build everything, `cd` into the `part9/` directory and run:
|
||||
|
||||
```shell
|
||||
elm make src/Main.elm --output ../server/public/elm.js
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1"
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/parser": "1.0.0",
|
||||
|
||||
@@ -40,7 +40,7 @@ import Html.Attributes exposing (class)
|
||||
import Html.Events exposing (stopPropagationOn)
|
||||
import Http
|
||||
import HttpBuilder exposing (RequestBuilder, withBody, withExpect, withQueryParams)
|
||||
import Json.Decode as Decode exposing (Decoder, bool, int, list, string)
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
import Json.Decode.Pipeline exposing (custom, hardcoded, required)
|
||||
import Json.Encode as Encode
|
||||
import Markdown
|
||||
@@ -83,6 +83,47 @@ type Article a
|
||||
= Article Internals a
|
||||
|
||||
|
||||
{-| Metadata about the article - its title, description, and so on.
|
||||
|
||||
Importantly, this module's public API exposes a way to read this metadata, but
|
||||
not to alter it. This is read-only information!
|
||||
|
||||
If we find ourselves using any particular piece of metadata often,
|
||||
for example `title`, we could expose a convenience function like this:
|
||||
|
||||
Article.title : Article a -> String
|
||||
|
||||
If you like, it's totally reasonable to expose a function like that for every one
|
||||
of these fields!
|
||||
|
||||
(Okay, to be completely honest, exposing one function per field is how I prefer
|
||||
to do it, and that's how I originally wrote this module. However, I'm aware that
|
||||
this code base has become a common reference point for beginners, and I think it
|
||||
is _extremely important_ that slapping some "getters and setters" on a record
|
||||
does not become a habit for anyone who is getting started with Elm. The whole
|
||||
point of making the Article type opaque is to create guarantees through
|
||||
_selectively choosing boundaries_ around it. If you aren't selective about
|
||||
where those boundaries are, and instead expose a "getter and setter" for every
|
||||
field in the record, the result is an API with no more guarantees than if you'd
|
||||
exposed the entire record directly! It is so important to me that beginners not
|
||||
fall into the terrible "getters and setters" trap that I've exposed this
|
||||
Metadata record instead of exposing a single function for each of its fields,
|
||||
as I did originally. This record is not a bad way to do it, by any means,
|
||||
but if this seems at odds with <https://youtu.be/x1FU3e0sT1I> - now you know why!
|
||||
See commit c2640ae3abd60262cdaafe6adee3f41d84cd85c3 for how it looked before.
|
||||
)
|
||||
|
||||
-}
|
||||
type alias Metadata =
|
||||
{ description : String
|
||||
, title : String
|
||||
, tags : List String
|
||||
, createdAt : Time.Posix
|
||||
, favorited : Bool
|
||||
, favoritesCount : Int
|
||||
}
|
||||
|
||||
|
||||
type alias Internals =
|
||||
{ slug : Slug
|
||||
, author : Author
|
||||
@@ -170,39 +211,15 @@ internalsDecoder maybeCred =
|
||||
|> custom metadataDecoder
|
||||
|
||||
|
||||
type alias Metadata =
|
||||
{ description : String
|
||||
, title : String
|
||||
, tags : List String
|
||||
, favorited : Bool
|
||||
, favoritesCount : Int
|
||||
, createdAt : Time.Posix
|
||||
}
|
||||
|
||||
|
||||
metadataDecoder : Decoder Metadata
|
||||
metadataDecoder =
|
||||
{- 👉 TODO: replace the calls to `hardcoded` with calls to `required`
|
||||
in order to decode these fields:
|
||||
|
||||
--- "description" -------> description : String
|
||||
--- "title" -------------> title : String
|
||||
--- "tagList" -----------> tags : List String
|
||||
--- "favorited" ---------> favorited : Bool
|
||||
--- "favoritesCount" ----> favoritesCount : Int
|
||||
|
||||
Once this is done, the articles in the feed should look normal again.
|
||||
|
||||
💡 HINT: Order matters! These must be decoded in the same order
|
||||
as the order of the fields in `type alias Metadata` above. ☝️
|
||||
-}
|
||||
Decode.succeed Metadata
|
||||
|> hardcoded "(needs decoding!)"
|
||||
|> hardcoded "(needs decoding!)"
|
||||
|> hardcoded []
|
||||
|> hardcoded False
|
||||
|> hardcoded 0
|
||||
|> required "description" (Decode.map (Maybe.withDefault "") (Decode.nullable Decode.string))
|
||||
|> required "title" Decode.string
|
||||
|> required "tagList" (Decode.list Decode.string)
|
||||
|> required "createdAt" Timestamp.iso8601Decoder
|
||||
|> required "favorited" Decode.bool
|
||||
|> required "favoritesCount" Decode.int
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.0",
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"NoRedInk/json-decode-pipeline": "1.0.0",
|
||||
"NoRedInk/elm-json-decode-pipeline": "1.0.0",
|
||||
"elm/browser": "1.0.0",
|
||||
"elm/core": "1.0.0",
|
||||
"elm/html": "1.0.0",
|
||||
@@ -16,7 +16,7 @@
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"lukewestby/elm-http-builder": "6.0.0",
|
||||
"rtfeldman/elm-iso8601": "1.0.1",
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.0.0",
|
||||
"rtfeldman/elm-validate": "4.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
|
||||
3134
intro/server/package-lock.json
generated
3134
intro/server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user