Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Power of Elm in JavaScript

The Power of Elm in JavaScript

How to bring some elm power in JavaScript. Is it possible? Let's see!

Franzé Jr.

August 12, 2017
Tweet

More Decks by Franzé Jr.

Other Decks in Technology

Transcript

  1. elm

  2. Imperative a = b + c if we change b,

    a will NOT be updated.
  3. Me writing Haskell: 30% test coverage. Scala: 60% test coverage.

    Ruby: 97% test coverage. Guess the order of reliability of code...
  4. !

  5. // @flow import { Record, Map } from "immutable"; import

    FormType from "./FormType"; import QuestionSubmissionType from "./QuestionSubmissionType"; export default class Model extends Record({ form: new FormType(), submissions: new Map(), currentStep: 0, submitted: false, errors: new Map(), apiKey: "" }) { form: FormType; submissions: Map<string, QuestionSubmissionType>; currentStep: number; apiKey: string; }
  6. // @flow import { Record, Map } from "immutable"; //

    --> import FormType from "./FormType"; import QuestionSubmissionType from "./QuestionSubmissionType"; export default class Model extends Record({ form: new FormType(), submissions: new Map(), currentStep: 0, submitted: false, errors: new Map(), apiKey: "" }) { form: FormType; submissions: Map<string, QuestionSubmissionType>; currentStep: number; apiKey: string; }
  7. function decodeForm(data: ApiForm): FormType { // Decode the questions on

    their own const questions = List(data.questions.map(decodeQuestion)); return 0; return new FormType({ id: data.id, applicationId: data.application.id, completionContent: data.completion_content, sections: List( data.sections.map(section => { return decodeSection(section, questions); }) ), persisted: true }); }
  8. ➜ formulae_react git:(master) flow status src/output_lib/decoders.js:201 201: return 0; ^

    number. This type is incompatible with the expected return type of 198: function decodeForm(data: ApiForm): FormType { ^^^^^^^^ FormType src/output_lib/decoders.js:202 202: return new FormType({ ^ unreachable code Found 2 errors
  9. ➜ formulae_react git:(master) ✗ flow status src/output_lib/decoders.js:199 199: let a

    = b; ^ identifier `b`. Could not resolve name Found 1 error
  10. ➜ formulae_react git:(master) ✗ flow status src/output_lib/decoders.js:199 199: let a

    = "hello" * 5; ^^^^^^^ string. The operand of an arithmetic operation must be a number. Found 1 error
  11. ➜ formulae_react git:(master) ✗ flow status src/output_lib/decoders.js:203 203: timesTwo("hello"); ^^^^^^^

    string. This type is incompatible with the expected param type of 198: function timesTwo(x: number) { ^^^^^^ number Found 1 error
  12. const Person = { get: (name: string): Promise<PersonType> => {

    return api.get(`${name}`).then(resp => decodePersonType(resp.data)); } };
  13. import { Record } from 'immutable' export default class PersonType

    extends Record({ name: '', age: 0, github: '' }) { name: string age: number github: string }
  14. type ApiPerson = { name: string, age: number, github: string

    } decodePersonType(person: ApiPerson) : PersonType{ return new PersonType({ name: person.name, age: person.age, github: person.github }) }
  15. function decodeForm(data: ApiForm): FormType { // Decode the questions on

    their own const questions = List(data.questions.map(decodeQuestion)); return new FormType({ id: data.id, applicationId: data.application.id, completionContent: data.completion_content, sections: List( data.sections.map(section => { return decodeSection(section, questions); }) ), persisted: true }); }
  16. function encodeForm(form: FormType): ApiForm { return { id: form.persisted ?

    form.id : undefined, application_id: form.applicationId, completion_content: form.completionContent, sections: form.sections.toArray().map(encodeSection), uuid: form.persisted ? undefined : form.id }; }
  17. // @flow import { Record, List } from "immutable"; import

    SectionType from "./SectionType"; export default class FormType extends Record({ id: "", applicationId: "", sections: List(), completionContent: "", persisted: false }) { id: string; applicationId: string; sections: List<SectionType>; completionContent: string; persisted: boolean; }
  18. type ApiForm = { id: number, application: ApiApplication, completion_content: string,

    sections: Array<ApiSection>, questions: Array<ApiQuestion> };
  19. import Html exposing (..) -- MODEL type alias Model =

    { ... } -- UPDATE type Msg = Reset | ... update : Msg -> Model -> Model update msg model = case msg of Reset -> ... ... -- VIEW view : Model -> Html Msg view model = ...
  20. ... const routesMap = { HOME: "/", // action <->

    url path PRODUCT: "/product/:id" // :id is a dynamic segment }; ...
  21. const productsReducer = (state = init(), action = {}) =>

    { switch (action.type) { case "HOME": ... case "PRODUCT": ... ...
  22. ... const mapDispatchToProps = dispatch => ({ goToProducts: id =>

    dispatch({ type: "PRODUCT", payload: { id: id } }) }); ...