Posts

Showing posts from 2018

cats/cats-effect and webservices function composition

cats/cats-effect and webservices function compositionIf you use webservices, say in a CLI program, then you are familiar with the following pattern:// typing in the types to show what they are...val entityA: IO[Option[A]]= getAByName("aname")val entityB: IO[Option[B]]= getBByName("bname")// ...// useIt does not return an Option.def useIt(a: A, b: B,...): IO[D]={...}// how do you call `useIt`?Here, the input “aname” comes from the user and is not a primary key (PK). The “get” has to search a list and if it finds a result, returns a single object. Or if the name is not found, it returns None. If the request finds more than 1 value, perhaps it returns None or signals an error (your choice).This is a classic problem in scala, that is, the effects returned in the get*ByName functions have efffect wrappers and we need to unwrap/drill-into them to use the data inside. There are also a few other other concerns that also come up:Can we find all the issues with the inputs p…

skip scalajs-bundler, use npm/webpack directly with sbt/scalajs

skip scalajs-bundler, use npm/webpack directly with sbt/scalajsMany people are using scalajs-bundler to specify their javascript dependencies using npm-style (sbt first, npm second) declarations.You don’t need to use scalajs-bundler, which can be confusing to use or perhaps less useful in complex bundling scenarios. If all you need is some simpler webpack config, use scalajs-bundler and ignore the content below. If not, you can still retain the flexibility of running npm after your compile triggers on source code change using the standard approach shown below.First, set up a webpack config. Only the relevant parts are shown:// config file myapp.webpack.config.jsconst common ={...whatever you want....}// I typically parameterize the scala.js output based on the// build kind but you can also be explicit if you wishconst prod ={ mode:"production",// prod by default, webpack 4 entry: path.resolve(__dirname,"target/scala-2.12/me-opt.js"), plugins:[newwebpack…

add editor state vars with typescript an recompose

add editor state vars with typescript an recomposeIf you need to add editor state to any class you can use recompose.Here’s the basics:/** What the output of [addEditorState] will receive as input. */exportinterfaceEditorProps{ isDirty:boolean isEditing:boolean setDirty:(v:boolean)=>void setEditing:(v:boolean)=>void resetDirty:()=>void resetEditing:()=>void}and the recompose part:/** * HOC to add isDirty and isEditing state management plus a few functions. * Input component goes from from `P extends EditorProps` => `P omit EditorProps`. */exportfunction addEditorState<P extendsEditorProps>(component: React.ComponentType<P>){return compose<P, Omit<P, EditorProps>>(withState("isEditing","setEditing",false),withState("isDirty","setDirty",false),withHandlers({ resetDirty:({ setDirty })=>()=>setDirty(false), resetEditing:({ setEditing })=>()=>setEditing(false)}))(component)}Note t…

thougthfulness of facebook's reasonml and reasonreact

Facebook recently released 0.3 version of reason and reasonreact for creating UIs. Instead of using typescript, you would use reasonml. reasonml is based on OCaml which has both functional and OOP capabilities. Why is how facebook is integrating reasonml into their ecosystem brillant? facebook recognizes that the ocaml syntax is a burden to learn. reasonml is a more javascript oriented syntax of ocaml. ocaml syntax is, as many functional languages are, harder to learn than say google’s go or really it’s difficult if you are not used to functional syntax. syntax is a big burden for migration of existing devs. The great part is that they are making it easy for a certain group, such as js programmers, to migrate.facebook has created reasonreact using only a subset of ocaml. No OOP components. And they reduce the surface area of the reactjs APIs to something appropriate for the functional world. The API is small and easy to learn. It does not offer everything that the reactjs API offers b…

codemirror, react and height sizing.md

codemirror, react and height sizing.mdIf you use codemirror and react together, say through react-codemirror2, then you may have run into sizing issues.Out of the box, codemirror has a style height setting to 300px on the outer div with classname CodeMirror. react-codemirror2 wraps this with another div called react-codemirror2.If you don’t load the CSS correctly, the default height of the component is 300px, which is rarely what you want. You generally want the editor to resize based on your overall layout. However, you may have found it difficult to do so. I certrainly did.The secret is to realize that codemirror add its own scrollbars and manages scrolling in order to optimize content rendering. There are really two modes for setting the height:Set the size of the outer container explicitly with a hight, say 500px using editor.setSize() however this does not refresh when the page changes size.Allow for dynamic resizing but ensure that the the component knows how tall it is.Generall…

pass through from typescript to babel.md

pass through from typescript to babel.mdI often use typescript just for types and not for bundling or transpilation to different ES targets.Typescript can play a few different roles that when used with a complex stack, can cause tooling confusion. To avoid confusion, I generally have typescript do as little as possible.To have typescript passthrough everything to babel, which is configured to transpile down to my target, I set tsconfig.json to:module: esnext => target an ES version that understands import/export natively.moduleResolution: node => resolve modules using node semantics. This is the default, but when “module” is used, it seems to get reset to a bad value.target: esnext => target the latest es environment for destructuring, default args, etc.jsx: preserve: => Keep brackets (see below).importHelpers; true => If typescript does happen to transpile, import tslib instead of writing some boilerplate into each output module. This saves spacenoEmitHelpers: true =&g…