<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Ville M. Vainio on Medium]]></title>
        <description><![CDATA[Stories by Ville M. Vainio on Medium]]></description>
        <link>https://medium.com/@vivainio?source=rss-5fcb0d5f9b46------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*1b5uveYv7S3-vDDA.jpeg</url>
            <title>Stories by Ville M. Vainio on Medium</title>
            <link>https://medium.com/@vivainio?source=rss-5fcb0d5f9b46------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 08 Feb 2024 20:03:36 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@vivainio/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Migrating to Python 3 in 3 minutes or less]]></title>
            <link>https://medium.com/@vivainio/migrating-to-python-3-in-3-minutes-or-less-11204364d969?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/11204364d969</guid>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Fri, 03 May 2019 17:57:47 GMT</pubDate>
            <atom:updated>2019-05-06T09:00:55.218Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*OtCdVpW-K8TGbcEloetFbw.jpeg" /></figure><p>… on Windows.</p><p>When you install Python 3, there will be a lancher called <em>c:\Windows\py.exe</em>. Barring weird stuff, this will be in your PATH. Stop using <em>python.exe</em> and start calling that. You can call <em>py -2 myscript.py</em> to use Python 2 instead, and <em>py -m pip &lt;somepackage&gt; </em>to use pip for Python 3.</p><p>Use <em>futurize </em>to port your code. “<em>futurize -w .” </em>rewrites all files in current directory with fixed versions. Most importantly this adds <em>from __future__ import print_function </em>to your file. It’s directly in Anaconda distribution, or you can install it with <em>“py -m pip install future”</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=11204364d969" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Clean Code]]></title>
            <link>https://medium.com/@vivainio/clean-code-31aac2dfb155?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/31aac2dfb155</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[clean-code]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Mon, 10 Dec 2018 17:28:24 GMT</pubDate>
            <atom:updated>2018-12-10T17:28:24.200Z</atom:updated>
            <content:encoded><![CDATA[<p>Again, there is controversy around Robert C. Martin (known as “Uncle Bob” among his following), because of Trumpster sympathy accusations (which, even if they were proven, are not unusual for a man of his age).</p><p>At times like this, it’s good to study his earlier work, “Der saubere Code” (or “Clean Code”) to gain some perspective and make it evident that these accusations are without basis. It introduces a doctrine called SOLID, outlined below:</p><p><strong>Single Responsibility Principle</strong></p><p>Evolution of code must lie in hands of singular, animating principle, embodied by an anointed Leader.</p><p><strong>Open/Closed Principle</strong></p><p>Libraries should be Open for Use, but the decisions within the library must be Closed, stewarded by an educated board.</p><p><strong>Liskov substitution principle (</strong>Liskovsches Substitutionsprinzip)</p><p>Manages relationships between Master- and subclasses. Subclasses, while independent, must always obey the rules set by Master Class, while retaining freedom to add their own functionality.</p><p><strong>Interface segregation principle</strong></p><p><strong>“</strong>To each their own” — different capabilities and freedoms fall naturally to different classes of users.</p><p><strong>Dependency inversion principle</strong></p><p>High level, policy-setting components should be independent of lower level components. Top tier is the unmovable, unquestioned layer that provides stability, while lower tiers go about their ways with little danger of disruption to the Whole.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=31aac2dfb155" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[As Spoken by a Dead Enterprise Developer by the Tree]]></title>
            <link>https://medium.com/@vivainio/as-spoken-by-a-dead-enterprise-developer-by-the-tree-899e2d69e664?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/899e2d69e664</guid>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Mon, 26 Nov 2018 20:21:02 GMT</pubDate>
            <atom:updated>2018-11-27T15:44:22.015Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LjL8YlDyyXfKG0Ilzv4VeA.jpeg" /></figure><p>Programmer said,</p><p><strong>1. </strong>Like a good shepherd gently corrects the route of a wayward lamb, the shepherd of an application steers the code towards safer paths without coercing or blaming the code.</p><p><strong>2.</strong> You have been told that you should use backslash in Windows as a path separator. But know that backslash is an abomination in my house and should only be used as an escape character. Let Windows software that breaks without backslash break, and let us not talk about that software anymore.</p><p><strong>3.</strong> Man that thinks too much looks at an idea and thinks he can do better, and spends his nights belaboring for the perfect implementation without typing in the program. But his wise neighbor implements his first idea, sees how it operates and modifies it accordingly. His neighbor is blessed with riches and respect, while the man starves and is ridiculed.</p><p><strong>4.</strong> You say you should depend on interfaces and not concretions. Yet you put the interface in the same dll as the implementation, like a drunkard that soils his pants also on the outside. Know that interface is of no use if it can not be used without dragging along the implementation.</p><p><strong>5.</strong> If you inject your dependencies, you can have different life cycles and states within those dependencies. But transient dependency is almost like a static function when you look close enough.</p><p>Programmer said,</p><p><strong>6.</strong> You were told to write many unit tests. Yet the man that told you, does not write unit tests in the privacy of his own house. Words are wind, and man is judged by his deeds, not his words.</p><p><strong>7.</strong> Foolish young man sees a new library and knows that his elders don’t know it. So in order to acquire wives, the young man peacocks around with his knowledge above his elders, for surely he must be wiser than them. Instead, a wise man knows that the library was written by another such lovelorn young man, again to impress other people. Young man learns this from the wise man, studies computing outside JavaScript, and earns a respectable wife and a good house in his time.</p><p><strong>8.</strong> Foolish old man wants to teach the youth in his village. But they won’t listen to him because he is old and busted. Do not be that old man. Instead, be the wise old man that listens to the youth, for they get around the block more and have their own stories of war and conquest to tell. And then see what you can use and what you must discard.</p><p>Programmer said,</p><p><strong>9.</strong> You were said that Object Oriented is garbage and Functional Programming is too hard. But wise men know that Object Oriented programming is not garbage when done in moderation, and Functional Programming is not hard when done in moderation. And the village idiot, writing simple procedural programs in Go, laughs at both, with belly fat from rich foods and good life.</p><p><strong>10.</strong> But yet know that Haskell is doomed to obscurity, as for obscurity it was written and in obscurity it thrives.</p><p><strong>11.</strong> Text is bytes written as UTF-8. It shall not have a Byte Order Marker in the beginning, for that is an aBOMination. Let no more be said about that.</p><p>Programmer said,</p><p><strong>12.</strong> Many men you respect use Rust and you aspire to the same. But you should not use Rust before they fix their editor support, for the editor support is still bad.</p><p><strong>13.</strong> Wise man looks at code searching for expressiveness and clarity. But equally wise man accepts an ugly language if the tooling is built by rich masters with fanatic drive towards quality. Beautiful program will not keep you warm in winter breeze, but fast compiler just may.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=899e2d69e664" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating a Windows Forms GUI with F#]]></title>
            <link>https://medium.com/@vivainio/creating-a-windows-forms-gui-with-f-968b3ae75a82?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/968b3ae75a82</guid>
            <category><![CDATA[windows-forms]]></category>
            <category><![CDATA[microsoft]]></category>
            <category><![CDATA[fsharp]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Sat, 14 Jul 2018 20:50:43 GMT</pubDate>
            <atom:updated>2018-07-17T07:43:38.956Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/559/1*jAJoDLM4IRmo3EEls2IavA.jpeg" /></figure><p>Windows Forms is not dead — it’s now more alive than it has been for years now that Microsoft announced they will support it in <a href="https://blogs.msdn.microsoft.com/dotnet/2018/05/07/net-core-3-and-support-for-windows-desktop-applications/">.NET Core 3.0</a>, and that you will be able to<a href="https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/xaml-host-controls"> embed “modern” UWP controls</a> in Forms apps.</p><p>Besides not being dead, it has other things going for it:</p><ul><li>It’s easy to use from F#, as you’ll see from this post. WPF requires more complex adaptation work (e.g. there is a <a href="https://fsprojects.github.io/FsXaml/">XAML type provider</a>), while Forms is pretty much straight .NET.</li><li>.NET Native (i.e. the “full” UWP stack) does not work with F# at all, and possibly never will — so it’s probably not going to be relevant to your choices.</li><li>Windows Forms uses the programming pattern familiar from Qt and other UI toolkits, so you can pretty much get going in a day.</li><li>It’s not a particularly good fit for “rich” or customized UI’s, but you are not writing those anyway. When you have someone paying you to do a rich UI for desktop, they are paying to do it on the Web.</li><li>It’s the real Native toolkit for Windows, so the applications can be very small. An application that does something can happen in 20kB (without F# of course, F# adds ca. 3MB of weight).</li><li>Windows Forms, unlike WPF or UWP, has a cross platform story and can be run in Mono under Linux/Mac.</li></ul><h4>With F# you say?</h4><p>The problem with GUI programming with F# is that UI design tools are written for C# and VB programmers. The recommended approach has usually been to:</p><ul><li>Create the GUI logic in C#, using the Forms UI Designer.</li><li>Use F# to make libraries and call out to them from the GUI.</li></ul><p>The obvious problem with this is that you don’t really want to use C# more than necessary, and want to keep language context switching to the minimum — not to mention that you are limited to constructs that are well supported on C# side on the boundary.</p><p>Another approach, probably only appropriate for seasoned Forms developers, is to write everything in F# without using the Designer. This is outlined at least in the (excellent) “<em>Expert F#</em>” book, if you are curious how to do it.</p><p>The alternative approach I’m proposing here is to also write all the GUI logic in F#, only dropping to the C# side when you want to move things around in the Forms Designer. Your main entry point is the F# application, which then instantiates the main form (and subsequent forms). The forms register all their UI components with a “behind” class, which then binds the event handlers and implements all that hairy GUI logic in a language that is more aesthetically pleasing (that’s F#, if you are new here).</p><p>I’ll take a shortcut and use a <a href="https://github.com/vivainio/scaffer-templates">Scaffer template</a> to create the app skeleton:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/686/1*zhmw1J5UeS3fId7uN_-xQw.png" /></figure><p>Yikes! That was a lot of stuff. Fear, not, you only ever need to care about few of them. If you click through the files, you’ll notice that:</p><ul><li>MathManDesign is a project (DLL) written in C#. That’s the one you’ll open in VS and click around the Designer.</li><li>MathManMain is the “main” application (“EXE”). It contains the entry point which bootstraps Windows Forms, instantiates the MathManForm and hooks up the “behind” class. It takes a project reference to MathManDesign project, but MathManDesign does not have any kind of reference to MathManMain. Therefore, you can go wild in using F# constructs that have usability issues when exposed to C# (e.g. DU’s). This dependency “inversion” is done by <a href="https://github.com/vivainio/TrivialBehinds">TrivialBehinds</a>, a micro-DI-library available in nuget.</li></ul><p>When you build and launch the application, you’ll see the minimal default functionality in action:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/301/1*_vT2FfVc10uxKW_SzxV36g.png" /></figure><p>(to verify the behavior, I recommend clicking the button a few times and observing how the number after “Lorem ipsum“ in the label increments on each click).</p><p>It looks like this in the designer (double-click on MathManForm.cs to see the Design view):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/373/1*VcBCTfXg-N9bVWorBO3SqA.png" /></figure><p>And press f7 to get to the code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ba78ed22817a3c1cfbaf2f0dcff975cb/href">https://medium.com/media/ba78ed22817a3c1cfbaf2f0dcff975cb/href</a></iframe><p>After editing the form in the designer, you’ll add the new controls that it created in the MathManUi class. This is the <strong>only </strong>C# code you’ll need to keep up to date (of course it needs to be added for every Form you create). You can copy-paste the control declaration from MathManForm.Designer.cs.</p><p><em>Update: </em>you can replace this boilerplate by CreateComponentBehind, if you want to expose the whole MathManForm instead of of MathManUi. In that case you need to make the controls public:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6913036bbe94cf176fdb9435a7e18fe0/href">https://medium.com/media/6913036bbe94cf176fdb9435a7e18fe0/href</a></iframe><p>Now, let’s take a peek at the F# code running it all:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a3d8028cd15cfddb2e8b324f0582dfba/href">https://medium.com/media/a3d8028cd15cfddb2e8b324f0582dfba/href</a></iframe><p>That’s it!</p><p>The first lines of main are standard Windows Forms bootstrap code. Then we instantiate the Form and start the application. The instantiation of the form instantiates the “behind” we registered in registerBehinds() function.</p><h4>Doing it from scratch</h4><p>Warning: stop reading if you are already bored.</p><p>I “cheated” a bit by using a template — because some boring work went into getting it working. For the posterity, here’s what was needed to get that F# application off the ground:</p><ul><li>Create a solution</li><li>Create the F# application as “Console application” and reference Windows.Forms and System.Drawing from there.</li><li>Set the application type of the F# application to WinExe (otherwise you’ll get that empty terminal when running the application)</li><li>Create the Design project, in VS 2017 “new project wizard” it’s “Windows Forms Control Library (.NET Framework)”.</li><li>The .NET Framework to use should be .NET Framework 4.7.2, because <a href="https://docs.microsoft.com/en-us/dotnet/framework/winforms/high-dpi-support-in-windows-forms">font rendering will be fuzzy on Windows 10</a> on 4.6 series and older.</li><li>In order to fix font rendering, I had to modify App.config (check the link above), and create a manifest in the F# application. To do that, I just did “Add manifest” on the Design project and copied it over to F# application side.</li><li>Since you’ll have multiple projects, it’s good idea to migrate to Paket.</li><li>Add a nuget dependency to TrivialBehinds to both projects. You can probably get similar behavior with “actual” DI libraries (get class X that supports handling data package Y), but I couldn’t be bothered to add one of those heavy injectors here.</li></ul><p>The skeleton code is at <a href="https://github.com/vivainio/FSharpFormsSkeleton">https://github.com/vivainio/FSharpFormsSkeleton</a> — I’ll probably keep it up to date and modify the template if/when needs arise. If you are using that instead of Scaffer, you need to do some IDE legwork to rename those classes.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=968b3ae75a82" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[14 (fourteen) habits of Okay Programmers]]></title>
            <link>https://medium.com/@vivainio/ten-habits-of-okay-programmers-74a04746dfe0?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/74a04746dfe0</guid>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Tue, 12 Jun 2018 19:03:29 GMT</pubDate>
            <atom:updated>2018-06-16T20:32:54.169Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*4XemvUaTPkKwQ48PfaJAng.jpeg" /><figcaption>Mastery is Grind</figcaption></figure><p>Setting the stage: you are a fresh mind entering the field. You don’t want to suffer from imposter syndrome or bear the dreaded mark of a “pleb”, but are confused on how to navigate the bewildering array of chaotic undercurrents in Real Programmer subculture. By practicing these simple steps you can ride that tiger all for all it’s worth.</p><ol><li>Master the command line. You will be running lots of scripts and launch stuff from there, so why not get fluent at it?</li><li>Never have spaces in file or directory names, or anywhere else for that matter. If you get caught using one, you will be assumed to be “GUI-clicker” and beyond all repair. If your code is under a directory with a space in the name (or two in some extreme scenarios, I kid you not), it’s assumed to be garbage regardless of whether it was written by John Carmack himself.</li><li>Learn to think in types. If you are only doing dynamic programming languages at work, use a typed one at home. If you can’t think in types, your skills are assumed to be lacking regardless of your proven productivity or success in private life.</li><li>Learn a <strong>typed functional programming language</strong> (OCaml, F#, Scala, ReasonML, Haskell…). No matter how bad a programmer you really are, or however “unpopular” programming language (PHP, ES5, Java, …) you are forced to crank out at your day job , you are assumed to be on the top tier if you can comfortably sling one of these. Using Clojure or Elixir doesn’t count because1) these don’t have types and 2) they are perceived as “trend hopper” targets for the now-disbanded Ruby tribe. If you can be productive in Idris or other dependently typed language, you are assumed to be a Programming God despite never having closed a ticket you were supposed to work on. <strong>Extra caution</strong>: using Haskell may be perceived as “trying too hard”.</li><li>Only drink on Fridays. This ensures you have regained your mental acuity and creativity by Monday lunch time or Tuesday morning (depends on your age and stamina).</li><li>Solve as many problems as you can. If you don’t encounter interesting problems in your current tasks, help other people solve their problems or create side projects where you can practice solving new interesting problems.</li><li>Code as much as you feel like. 8 hour workday can only fit certain amount of coding, and you can certainly be “good enough” for your employer if you stick to that. But if you code more, you will be better. Programming is practice, practice, practice. People will routinely tell you otherwise, but parents also tend to compliment the singing of their children.</li><li>If you have to draw pictures to understand something, draw them on pencil-and-paper. Git is where your work output should go. Like the sound of tree falling in the forest without anyone listening, work that didn’t end up in Git will be perceived as work that didn’t happen. <strong>Exception</strong>: if you helped someone land something in Git, you can rationalize having sort of kind of done useful work (maybe).</li><li>If you are male, try growing a beard if you can. You don’t have to wear it at all times, but at least ensure there is a verified scenario where you, in fact, were seen as having sufficient amounts of beard. If you are a woman, moderation is advised regardless of whether you can grow one or not.</li><li>Do not use shell scripting languages (bash or .bat/.cmd files, or Powerhell) if you have more than 2 lines of “code”. Use Python (or Ruby if you must) instead. If someone doesn’t have Python installed, he’s not worthy of running your scripted masterpiece anyway.</li><li>Have hobbies outside programming. At least read a book or play some video games sometimes for chrissake.</li><li>Acquire a good arsenal of so called “thought leaders” you follow in Twitter. They should mostly consist of battle-hardened veterans aged 35 or above. The younger ones will lead you down the swamp of Node and other subcultures that are not perceived to be sufficiently programmer-y. On the other hand be wary of exceedingly old thought leaders that are perceived to be out of style (like “Uncle Bob”, or SOLID patterns in general).</li><li>Follow programming news. On Reddit, <a href="https://old.reddit.com/r/programming/">/r/programming</a> and <a href="https://old.reddit.com/r/programmingcirclejerk/">/r/programmingcirclejerk</a> provide affordable value at good regularity. HackerNews (also known as the “orange website” because the maintainers <a href="https://news.ycombinator.com/">can’t do CSS</a>) has a small cult following, but 1) you can’t get “just programming news” from there and 2) the community (a.k.a “<a href="http://n-gate.com/">webshits</a>”) overall is annoying and verbose, and reading too much of their output can lead to reduction of social skills, such as they are.</li><li><strong>“It’s nice to be important but it’s more important to be nice”</strong>, to paraphrase a <a href="https://en.wikipedia.org/wiki/H.P._Baxxter">German philosopher</a>. If you are an Okay Programmer but arrogant or mean, you will be like that clunky old cog in a machine that just gets to stay there because yanking it out would require disassembling too much other stuff.</li></ol><p>Your mileage may vary, and this blog post should not be treated as Gospel. For one, it was written by single author (as opposed to Gospels, of which there are four at the time of writing this).</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=74a04746dfe0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[MobX with Angular, Part 2: Patterns, Perks and Gotchas]]></title>
            <link>https://medium.com/@vivainio/mobx-with-angular-part-2-patterns-perks-and-gotchas-37e2a393e0eb?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/37e2a393e0eb</guid>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[mobx]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[typescript]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Mon, 30 Apr 2018 20:07:13 GMT</pubDate>
            <atom:updated>2018-05-02T14:49:52.359Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/760/1*NxzzwQj3ffG0jugGdFrP2w.jpeg" /><figcaption>State management shouldn’t be rocket science</figcaption></figure><p>This is the second installation of the critically acclaimed “MobX with Angular” series. If you came here googling for “ngrx alternatives sweet jesus make it stop”, you are in the right place. You probably want to read <a href="https://medium.com/@vivainio/mobx-with-angular-the-prelude-1c0dcfb43fe6">part 1</a> for the basics (or any generic React-oriented MobX tutorial if you don’t particularly like my writing).</p><p>On to the non-basics. We are creating a big Angular application with a largish, geographically distributed team at <a href="https://www.basware.com/">Basware</a>, and have established this as a pretty workable design (for the purposes of discussion I’m using the classical Blog Post feature as the example):</p><ul><li>The single source of truth is the Store, <em>posts.store.ts</em> (class <em>PostsStore</em>). It contains the @observable properties, and all the @action’s that modify the state.</li><li>There are many Stores. You could have <em>AuthorsStore</em>, <em>SettingsStore </em>etc.</li><li>Components don’t access (i.e. inject) the Store directly. Instead, they use a facade called <em>PostsService</em>, in <em>posts.service.ts</em>.</li><li>Http requests are done by <em>PostsApiService</em>, in <em>posts.api.ts</em>. This is the only place that knows what url’s are used. This is also a good place to put a breakpoint when wondering why on earth that one request was sent three times.</li></ul><h4>The Facade</h4><p><em>PostsService </em>is responsible for exposing parts of the Store to the components. That is, it’s what your <em>post-reader.component.ts</em> injects to do stuff.</p><p>If there is asynchronous http work to do, <em>PostsService</em> calls to <em>posts.api.ts</em> service (<em>PostsApiService</em>) that sends the request. <em>PostsService </em>then captures the response and updates the state accordingly (usually calling an action in Store). Here’s an example flow:</p><ol><li>User clicks a post. Component calls <em>postsService.documentChanged(id) </em>which is a hint that we want the data for that document.</li><li><em>PostService </em>notices that we don’t have that document in store. It triggers the fetch knowing it’s needed soon.</li><li><em>PostsReaderComponent </em>is observing <em>postService.getPost(id)</em>. It keeps returning <em>undefined </em>(or <em>null </em>if you are so inclined) for now. A busy spinner is spinning.</li><li><em>PostService </em>finally receives the post content. It calls the action <em>store.setPost(id, { content: “blah blah”})</em></li><li>The observer of <em>getPost(id)</em> is woken up now that the data changed, and it can place the content in a component instance variable. This dismisses the spinner and reveals the glorious post content.</li></ol><p>It’s worth mentioning that MobX itself has support for async workflows, through <a href="https://mobx.js.org/best/actions.html">async actions and flow()</a>. We are not using those because</p><ul><li>we want to stick with relatively tried-and-true async patterns familiar from AngularJS 1.x days</li><li>generators don’t work great (read: hardly at all) with current crop of debuggers and source maps</li><li>async is not exactly rocket science. Every action on the store is a dumb, instant “commit”.</li></ul><h4>createTransformer()</h4><p>You noticed the <em>postService.getPost(id)</em> above. It will probably look for the content in an observable <em>Map&lt;string, PostData&gt;</em>. You can call it in autorun body just fine, but there is actually a better and faster way.</p><p>Usually, MobX recommends doing most calculations in <em>@computed</em> properties instead of complex <em>autorun </em>bodies when you can:</p><ul><li>It’s faster. When a computed property is observed, it is “hot”. That is, when the data or other computed properties are modified, the computed values are pushed out and memoized. Just calling the computed property will get you the memoized value. If there are many components observing the same data in autoruns, they will be recalculated every time the data changes. With computed properties, the calculation is run only once. This means you can safely call them without worrying about performance under the hood.</li><li>They are a cleaner programming pattern. When you see something is computed, you know it’s just a pure projection of underlying state. And, you know you should be observing that state in the top level autorun() somewhere. Non-computed things could be doing anything else. You’ll probably implement your state by having a whole tree of projections refining and improving the state to fit your particular consumption needs.</li></ul><p>Now that I convinced you of their merits, here comes the Gotcha 1: <strong>you can’t pass arguments to computed functions</strong>. They are just getters with no arguments. You could just have “<em>currentPostId</em>” in store, and give data for that current post in the computed getters. But, this won’t work if you have multiple posts being observed at the same time (say, you have a two pane post reader showing different posts at the same time).</p><p>This is where <a href="https://mobx.js.org/refguide/create-transformer.html">createTransformer() in mobx-utils </a>steps in (if you understood none of the official description, read on). Here we create a <em>getPostAndAuthorData </em>(in <em>PostsService </em>class body) that reads stuff from two different transformers (projections):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8ab6f91401c51756d2bcc510fdae61a2/href">https://medium.com/media/8ab6f91401c51756d2bcc510fdae61a2/href</a></iframe><p>The call to <em>getPostAndAuthorData</em>() discovers the internal computation by looking it up by the <em>postId</em>. You can only pass one primitive argument to the transformation, but I know that you, Dear Reader, will usually be using a string <em>documentId </em>or somesuch. If you would need something more complex, eat it up and use <em>autorun</em>() instead.</p><h4>Component code</h4><p>In the end, you’ve got to be observing the data in autorun, otherwise it’ll all be for naught. For our application, we have made a utility to</p><ol><li>Create a list of autoruns.</li><li>Dispose them in ngOnDestroy().</li></ol><p>It’s used like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e13119f35fab3685e4f0df39082ec2ce/href">https://medium.com/media/e13119f35fab3685e4f0df39082ec2ce/href</a></iframe><p>The strings in there are names of the observables, so <a href="https://chrome.google.com/webstore/detail/mobx-developer-tools/pfgnfdagidkfgccljigdamigbcnndkod?hl=en">mobx-devtools</a> Chrome plugin (that also works with Angular) shows them nicely. You can grab the utilities (<em>startObservers</em>, <em>addComponentDisposer </em>and <em>stopObserving</em>) from <a href="https://github.com/vivainio/angularpack/blob/master/src/mobtool.ts">Github</a>. The first argument to <em>startObservers</em>() is optional; if you pass the component <em>ChangeDetectorRef </em>there, triggering any of the listed observers will also run change detection on that component. This is usually needed for OnPush components.</p><p>Why not shove everything in one autorun? The basic idea is to segregate them so that only the part that depends on a particular change is run when needed.</p><p>Natural place to “start observing” is <em>ngOnInit</em>(), since that is only run once per component, and the components input attributes have settled by the time it runs. You can delay the initialization of observables by MobX <em>when()</em> function that retuns a promise that resolves when the observed expression returns true:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/340f55e16097f541f02ef467458620bb/href">https://medium.com/media/340f55e16097f541f02ef467458620bb/href</a></iframe><h4>There is no such thing as free lunch</h4><p>With all this magic and rainbows, there’s got to be a price to pay, right? Well, there is, and sooner you know the better:</p><ul><li>Decorators like @observable and @computed can’t currently (as of Angular 5) be used in components because AoT compiler chokes up on them. <em>createTransformer</em>(), on the other hand, can be used, and can be handy for some marginal refinement you want to do at the edges. MobX 4 provides an alternative syntax using <em>declare(),</em> which won’t trigger this problem.</li><li>The observable data in stores is injected with MobX specific metadata, and the attributes of objects are transformed to getters/setters. This means you need to click individual properties in the debugger to investigate them.</li><li>Observable arrays look bad in the debugger. You will see hundreds of items per array, and need to click through the items to even see the length. Upcoming MobX 5 will fix this (by using ES6 proxies).</li><li>Some JavaScript libraries can when fail dealing with observable data structures. E.g. lodash <em>_.flatMap</em> (which is lodash version of <em>smooshMap()</em>) just fails to deliver with an observable array. To be fair, that’s the only bad lodash function that I know of, so no need to throw out lodash quite yet.</li></ul><p>The last three problems above can be avoided by using toJS() in your computeds/transformers/autoruns — so you won’t see the guts of observable data structures at the edges. You can also log stuff to console through toJS():</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a17b9c38a5684334bcd5a6b0a108f3a8/href">https://medium.com/media/a17b9c38a5684334bcd5a6b0a108f3a8/href</a></iframe><p>All that being said, the debugger experience with MobX is very good. If you set a breakpoint in autorun or computed property, you see precisely what triggered the change from the call stack — and the call stack fits on the screen, as opposed to anything involving RxJS observables.</p><h4>Should you still be using RxJS?</h4><p>A good rule of thumb is: not as much as you did.</p><ul><li>For dumb components that don’t want to take dependency to any kind of store, pass immutable objects as inputs, and reassign the value to trigger component update (for OnPush components).</li><li>Sometimes you have scenarios where component needs notification for events (as opposed to changing state as pure function of data in store — something you should do most of the time). Creating a <em>BehaviorSubject&lt;SomeSpecialEvent&gt;</em> in a service provided at component level is fine for that. The alternative of passing <em>@Output</em> events through every level can get cumbersome. Real life example: we are broadcasting events from ag-grid through a <em>BehaviorSubject</em> for the components above.</li><li>Methods in your http api services (e.g. <em>PostsApiService</em>) usually start the <em>HttpClient </em>observable and <em>map()</em> it a bit to mungle the data. If the logic gets complex enough to not be readily readable using RxJS (e.g. once you go beyond trivial <em>map()</em>), you shouldn’t be shy to run <em>.toPromise()</em> on the observable and use async/await. Your pull request reviewers will thank you for it.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=37e2a393e0eb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[MobX with Angular: the Prelude]]></title>
            <link>https://medium.com/@vivainio/mobx-with-angular-the-prelude-1c0dcfb43fe6?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/1c0dcfb43fe6</guid>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[mobx]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[reactive-programming]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Sun, 14 Jan 2018 19:37:26 GMT</pubDate>
            <atom:updated>2018-05-01T18:24:59.137Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/736/1*A9D1M7Uv3FprLXa3QAHN3A.jpeg" /><figcaption>Conan experimenting with NGRX</figcaption></figure><p>This is Part 1 of the in-progress article series. <a href="https://medium.com/@vivainio/mobx-with-angular-part-2-patterns-perks-and-gotchas-37e2a393e0eb">Part 2</a> with more advanced concepts is also available.</p><p>I hit a degree of analysis paralysis on writing an “all in one” blog post about using MobX on Angular (2+) at Basware, but it ended up being a bit heavy reading. Instead of that I’m doing a series of shorter, hopefully harder-hitting posts. (<em>Narrator: this one ended up being neither short, nor hard-hitting</em>)</p><p>Aim is not to teach you MobX, but rather to generate some appetite for the productivity wins you can reach with it — and maybe help you debug some of your personal misconceptions faster (I also had some in the beginning).</p><h4>The Store</h4><p>MobX is not really built around “Stores”. You can have your state spread over however widely you want (e.g. dozens of different Angular services or ES6 classes if you are so inclined). Simple state is always easier to track, but there is no need to cargo cult a single God-object to hold everything. The mechanics of MobX will work regardless of how you split your state.</p><h4>Observables</h4><p>There is probably a small subset of state that actually needs to change. These are marked by @observable decorator, and they are usually primitives, arrays, objects and ES6 Maps. Note that, for better or worse, you must use ES6 Maps instead of objects to represent dictionaries (as MobX can’t detect keys being added to objects). “Changing the state” means writing to these fields (mutating, reassigning, whatever).</p><h4>Computed properties</h4><p>@computed decorator marks an ES6 property getter that uses some of the observables defined above to calculate derivable parts of the state. If you have observable’s called “foo”, “bar” and “baz”, you can use computed properties to produce e.g. { foo, bar } object if both are defined, or null otherwise. You need that new unique object to trigger OnPush change detection, among other things. If “baz” property changed, your computed property comfortably sits as the old value, without unwanted triggers of OnPush change detection.</p><h4>Autorun</h4><p>This is where the actual magic happens.</p><p>Autorun is a function that:</p><ol><li>You probably have in your <em>ngOnInit</em>(). Class constructor is too early (e.g. Angular ChangeDetectorRef is not available there).</li><li>Is run once in the beginning. MobX records what properties (observable’s and computed’s) from MobX stores it accesses, and remembers its dependencies.</li><li>Is run again when any of your dependencies change.</li><li>Remains “hot” until you unsubscribe from it. autorun() returns a callable disposer that you will call in your <em>ngOnDestroy </em>for the component.</li></ol><p>What’s in your autorun() in a typical Angular application? You can have code that:</p><ul><li>Copies values from store to your local component variables that are used from the template.</li><li>Runs patchValue() on a Reactive Form within the component.</li><li>Does some last minute tuneups for the data to make it easier to access from the template.</li><li>Calls ChangeDetectorRef.detectChanges() to force Angular to check changes in case you are within a ChangeDetectionStrategy.OnPush component (and didn’t trigger any Input to change).</li></ul><p>A single component can have many autorun() blocks. The smaller and more granular the blocks, the more specific you can be about how often they fire.</p><p>Autoruns are not limited to components though! Services can have their own autorun’s observing the state, possibly initiating HTTP requests when interesting data is available in stores, and commit interesting responses back to the stores when they return.</p><h4>Don’t you need a new library for this?</h4><p>Not really. Core MobX works fine with Angular, with the scheme mentioned above.</p><p>We have a few convenience functions to help with disposing autoruns, like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c619bc222cab5870cfd34cd658dbaa3b/href">https://medium.com/media/c619bc222cab5870cfd34cd658dbaa3b/href</a></iframe><p>You call startObserving(this, () =&gt; …) in <em>ngOnInit</em>(), and stopObserving(this) in <em>ngOnDestroy</em>. There will be a new blog post with some more productized helpers later on.</p><p>There is also <a href="https://github.com/mobxjs/mobx-angular">https://github.com/mobxjs/mobx-angular</a> project that detaches a component completely from normal Angular change detection. It can work for your needs, but I posit that you may not need it, and operating directly with the (already simple) core MobX API can help when debugging problems in your own logic (e.g. “why did this not change? I better set a breakpoint in my autorun!”)</p><h4>How about Rx Observables?</h4><p>We started out by piping stuff from MobX as Rx observables to our components, as described here: <a href="https://netbasal.com/managing-state-in-angular-with-mobx-51191803e14f">https://netbasal.com/managing-state-in-angular-with-mobx-51191803e14f</a></p><p>Still, I was left wondering “y tho”. If you are just using autorun(), you avoid that unnecessary wrapper, and remove need to use async pipes. You just assign new immutable references (that you got from @computed getters or autoruns) to your component variables and their change detectors kick in.</p><p>MobX itself, despite its simplicity and ease of use, is a sophisticated reactive system on its own right. It just gives you the same power you get with Rx with a cheaper price tag (no need to do combineLatest(), switchMap() etc. to express a fundamentally simple computation).</p><h4>How about NGRX?</h4><p>Bright eyed and bushy tailed, we started out with NGRX; it has a very good industry buy-in, is based on React community darling Redux, and is being pushed by a cadre of Angular community hotshots. So it’s going to be the default conservative choice, right? Right?</p><p>It was a traumatizing experience for me personally. There was <strong>one directory with 5 files </strong>to represent something that was 5 lines with MobX — basically an array.</p><p>I wanted to give it a week to sink in, but I think I managed 2 days of zero productivity before calling off the experiment. Now, I have done some horrible things in my past (Symbian C++, raw GObject macro programming, 4GL’s, Perl…), but it’s 2018, I’m not getting any younger, and frontend development should be a bit fun and playful — experimenting with different state schemas and so on should be natural, energizing part of the work.</p><h4>Call to action</h4><p>So a degree of “Question authority” is in order here. If we see MobX as the better mousetrap for Angular, we should drive that point more consistently. We should start writing developer tools that illustrate the data flow on the screen. Barring everything else, we can at least make some noise in the blogs.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1c0dcfb43fe6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[PowerShell as find.exe replacement]]></title>
            <link>https://medium.com/@vivainio/powershell-as-find-exe-replacement-1d95498bc48e?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/1d95498bc48e</guid>
            <category><![CDATA[powershell]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Wed, 18 Oct 2017 17:17:54 GMT</pubDate>
            <atom:updated>2017-10-30T18:41:16.646Z</atom:updated>
            <content:encoded><![CDATA[<p>Or: how I learned to stop worrying and use a PowerShell feature.</p><p>Are you one of those guys that keeps trying to run “find” on Windows, and seeing that it runs some ancient MS-DOS command that nobody has used since the 80&#39;s? Not one to brick your scripts by prepending Cygwin commands to your PATH, you cringe in despair and reach out for alternatives.</p><p>So, PowerShell has a suprisingly reasonable alternative.</p><p>(“PowerShell!”, you say, againg cringing in despair. But fear not!)</p><p>The alternative is “Get-ChildItem”, aliased as “dir” and “ls”. Henceforth I’ll just use “ls” since “Get-ChildItem” is pedantic to the extent of being insulting.</p><p>The thing you will try first is “ls<em> -&lt;tab&gt; &lt;tab&gt; Recurse</em>” (yes, not pressing Tab a lot is going to slant your view heavily against PowerShell).</p><p>The output, as you expected, is useless. It lists the directories in separate paragraphs like the old “dir /s” MS-DOS command:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*hQTnWCNI8kLJX9B8LeeOBQ.png" /></figure><p>The remedy is to use the “-name” parameter that outputs full path names:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/477/1*aEnN-fFvPRk8Ok7axrGaSQ.png" /></figure><p>So now you’ll want to get just the directories:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/378/1*f-bTMtCyfpp6xfMustaX8g.png" /></figure><p>Or files starting with __:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/402/1*-rBlgoU1a89w5QVE5GsMzQ.png" /></figure><h4>Pipes</h4><p>“So what’s the deal? Everyone said PowerShell is all about piping objects?”, you say.</p><p>Well, if you omit the -Name argument you get those Objects. Happy now? These objects may be useful for some things, but you’ll want to use them to foreach stuff for all the files. For this purpose, these is the “<em>foreach” </em>command and $_.FullName:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/525/1*L94GzPePnPqGnUIaUd8gqQ.png" /></figure><p>This one runs “cat” on all the files. If you wanted to delete all the node_modules directories to free up disk space, you would do:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/859/1*zm32NSrTc34TygJzzi7nIA.png" /></figure><p>Clearly, this will fail on Windows because of path length limitations, but at least it will have deleted some of the node_modules directories.</p><p>Enjoy! And maybe use PowerShell.</p><p>Updating with new commands as I find them:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pcFUE9qu6RBlcGFpJHqY2w.png" /><figcaption>Get-Command as “which” replacement</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1d95498bc48e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using Stencil components in AngularJS application]]></title>
            <link>https://medium.com/@vivainio/using-stenciljs-components-in-angular-1-application-2f09287c151?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/2f09287c151</guid>
            <category><![CDATA[angularjs]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[stenciljs]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Sun, 17 Sep 2017 10:01:35 GMT</pubDate>
            <atom:updated>2017-12-29T13:58:47.742Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*TneQm8Qa4gqNi1LabVMxZw.jpeg" /></figure><p>Since <a href="https://stenciljs.com/">StencilJS </a>is just #UsingThePlatform (Web Components), I imagined it should be as easy (or easier) to integrate to an existing AngularJS (a.k.a Angular 1.x) app as one of those “jquery plugin” style direct DOM access libraries with imperative API. I tried that yesterday, and wasn’t disappointed.</p><p><strong>Why would I want this?</strong></p><p>Some reasons for being interested in this are:</p><ol><li>Improving the performance bottlenecks in your AngularJS application. Stencil components sit alone outside the digest cycle, so anything happening inside them doesn’t impact the outer Angular application. Also, every time you press a damn keyboard button in your &lt;input&gt; fields doesn’t cause the digest cycle to evaluate everything in your Stencil component.</li><li>Some complex things (that heavily alter the DOM structure beyond what ng-if’s etc. do) are easier in JSX, and don’t require PhD in AngularJS compiler trickery.</li><li>Creating complex components in Stencil makes them transferable to Angular 2/4/5 or whatever, when you decide to take the plunge of porting to a trendier framework.</li></ol><p><strong>How it works</strong></p><ol><li>You include the component assets with a &lt;script&gt; tag (this is important — don’t bundle the Stencil side, you need to have that script tag).</li><li>You slap the components in your template normally.</li><li>To change the props, you either set them imperatively on the HTMLElement or, for simple string properties, use angular {{ value }} binding.</li><li>To listen to events, bind the DOM Event listeners in you angular $postLink() method.</li></ol><p><strong>Example</strong></p><p>I used the StencilJS starter application to create a minimal component that showcases a few things: complex non-string object (‘strings’), simple string (‘simplestring’), and an event (‘onListClick’):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d89b5a98dc5f5d5b76a84521daf8750c/href">https://medium.com/media/d89b5a98dc5f5d5b76a84521daf8750c/href</a></iframe><p>I’m then using this component (descriptively known as ‘&lt;my-name&gt;’) in AngularJS template like so:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2af04b3f643a73d4ddda7b71174c3dc3/href">https://medium.com/media/2af04b3f643a73d4ddda7b71174c3dc3/href</a></iframe><p>The only “special” things here are</p><ol><li>being able to use {{$ctrl.message}} to assign values to the component directly in the template and</li><li>“Transclusion”, i.e. StencilJS “slots” working in the last my-name instantiation on line 19.</li></ol><p>Our Stencil component emits DOM Custom Events when clicking on list items; to listen to them in your AngularJS component you hook up some event listeners in $postLink() method (if you don’t know about $postLink() method, it’s one of the new component lifecycle methods in Angular 1.5):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/350c95bbe920bb48748808452bfbb888/href">https://medium.com/media/350c95bbe920bb48748808452bfbb888/href</a></iframe><p>When a complex object changes, you can’t just use {{ }} binding for obvious reasons. You need to explicitly dig up the HTMLElement for the component and assign value to this. You can use querySelector (or injected $element) to get a handle to the element:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f644f74ada8419a25fa671a3eea79423/href">https://medium.com/media/f644f74ada8419a25fa671a3eea79423/href</a></iframe><p>Note how I didn’t just Array.push() the new value in the object. To trigger the change for complex object, you need to create a new object by Object.assign, Array.concat or whatever strikes your fancy and assign that.</p><p>For more ergonomics, you may want to introduce “props” directive in your AngularJS application:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/25bbf07e01adfc219b7407adf93dbcc1/href">https://medium.com/media/25bbf07e01adfc219b7407adf93dbcc1/href</a></iframe><p>With this, you can set the properties of the component directly in html by doing:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b0857c085a14c9487b813759d345f682/href">https://medium.com/media/b0857c085a14c9487b813759d345f682/href</a></iframe><p>(source: see this <a href="http://plnkr.co/edit/7gvw0cqICfYZFAPi6bcG?p=info">plunkr </a>and <a href="https://github.com/angular/angular.js/issues/16235">github </a>issue)</p><p>The full example is <a href="https://github.com/vivainio/stencil-ng1-demo">here</a> in all its messy, unproductized glory.</p><p>Caveat: Stencil is not widely used in production yet (as of 17.9. 2017). Observe usual caution when evaluating this approach.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2f09287c151" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AngularConnect 2016 retrospective]]></title>
            <link>https://medium.com/@vivainio/angularconnect-2016-retrospective-96bfc790c7fa?source=rss-5fcb0d5f9b46------2</link>
            <guid isPermaLink="false">https://medium.com/p/96bfc790c7fa</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[angularjs]]></category>
            <dc:creator><![CDATA[Ville M. Vainio]]></dc:creator>
            <pubDate>Sat, 01 Oct 2016 07:28:43 GMT</pubDate>
            <atom:updated>2016-10-05T04:35:55.554Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jeZF8j0yQRGZf9mu2i7TSg.jpeg" /></figure><p>I went to AngularConnect 2016 (thank to my employer <a href="http://www.basware.com/about-us/careers">Basware</a> for sponsoring the trip), and am writing up some takeaways now that I still remember (something about) them, from the topic-specific sessions I attended.</p><h3>“Mini workshop: New Data Architecture” by Gerard Sans</h3><p>Recap of the basics, followed by tips on integrating Redux to an ng2 app. Fun detail: friendly reference to Redux as a “snob architecture” (immutable state), which rings true to some folks. GraphQL queries were also demoed.</p><h3>“The Angular 2 Compiler” by Tobias Bosch</h3><p>About the AoT compiler. Apparently an occasional internal nickname for the compiler was “Tobiler”, due to Tobias’ big influence on it. Tobias walked through 3 iterations on how the compiler was made incrementally better performing. The talk also included a JS performance tip on benefiting from “hidden classes” when a variable always has the same object (as in the final version of the AoT compiler).</p><p>Tobias seemed quite happy to showcase his baby (= compiler) in the talk.</p><h3>“Building Progressive Web Apps and Hybrid Apps with Ionic” by Adam Bradley and Brandy Carney</h3><p>Ionic is often understood as a framework for making native apps on Phonegap. Adam and Brandy demoed how easy it is to turn such an app to a progressive web app instead, switching to offline mode in chrome. Benefits of PWA’s over native apps were highlighted (search engine discovery, offline etc).</p><p>PWA’s could be an advantage for Ionic over React Native / NativeScript, so it was an interesting talk to catch.</p><h3>“Redux with AngularJS” by Pavithra Kodmad</h3><p>The only Angular 1 talk I watched (which is a bit of a shame, would have wanted to see Pete &amp; the guys gloating about the good job they did with 1.5). Pavithra inherited an Angular 1 app that had grown messy, and wanted to clean it up with Redux. She showed how to integrate Redux using ng-redux project, how store changes were automatically applied in $scope etc.</p><h3>“Optimizing Angular 2 Apps” by Martin Probst</h3><p>Aka “the revenge of Closure Compiler” (ok, Martin didn’t actually use that term). Martin used to be known as “guy that hates code” at Google due to his obsession with deleting and optimizing away unnecessary code. Showed a handy tool to analyze where the bloat comes in your application binary (<a href="https://www.npmjs.com/package/source-map-explorer">source-map-explorer</a>). Safe optimization strategies (like tree shaking) were described.</p><p>The really intriguing stuff, though, was the possibly upcoming ability to do property name shortening during minification. Closure Compiler can do that if you have sufficient type info (in JSDoc type annotations, generated with <a href="https://github.com/angular/tsickle">tsickle</a> tool from typescript source code). This is still a bit of a dangerous endeavour, but hopefully they can make it safer. This is an upcoming nice bonus if you are flying with TS (or have JSDoc annotated libs). Maybe time to also reconsider using Closure as your go-to minifier.</p><p>There was some overlapping themes with this and with Tobias’ talk, but you want to watch both from the web to get the full picture.</p><h3>“Why I am betting my future on Angular 2” by Shai Reznik</h3><p>Shai did some of his usual standup comedy’ish stuff, but ended up with a serious twist on why he is betting on Angular 2 (community stuff etc).</p><h3>Tuesday evening party</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gp5jrJ2GRmm4C-22WIxi_A.jpeg" /></figure><p>80’s theme disco (Human League ”Don’t you want me”, that kind of stuff). People enjoyed their time goofing around with costumes, throwing Frisbee etc.</p><p>I’m Finnish, and a programmer, so the time frame allocated for beer consumption was not fully sufficient to facilitate a safe space needed for relaxed fun &amp; merriment, but it was a good evening nevertheless.</p><h3>“Angular CLI” by Stephen Fluin</h3><p>Stephen described various nice things about the CLI. Frankly, I already forgot a lot of it, but an interesting new (for me) detail was how the CLI conceives the project as a full tree (“AST”-ish) and can do advanced heuristics based on that, instead of blindly doing dumb regexp replacements around.</p><h3>“The Angular Router” by Victor Savkin</h3><p>Victor showed off the final version of the router. Lazy loading got lots of stage time, and how angular-cli tooling will help with that. Webpack can cut the whole bundle in separate route-specific modules, that are then transparently loaded by the router. Useful pattern will be to load and show the initial bundle quickly, then to preload the later bundles while the user already using the app.</p><p>Victor’s router book was available as a free download through Tuesday, so hopefully you managed to catch a copy while it lasted.</p><h3>“Look Deeply Into Your App with Augury” by Igor Kamenetsky</h3><p>Igor explained some of the background and did a live demo of the debugger. Browsing the component tree, live-updating the attributes in the elements, dependency visualization and troubleshooting etc. Also covered on how Augury has evolved from early versions, and some nice tidbits of the implementation (frontend is a normal ng2 app running as chrome plugin, codebase is quite small at 5k LoC etc). I’m very much looking forward to having difficult problems to debug with this one ;).</p><h3>“How fast can web-apps be?” by Tim Ruffles</h3><p>This was actually a quite funny, “motivational” talk to watch if you caught some of the SPA framework fat-shaming going around on Twitter recently. Discourse was compared to a server-rendered forum (<a href="https://forum.dlang.org">https://forum.dlang.org</a>) when used on phones. Interesting observations thrown around:</p><ul><li>Blocking (non-async) script tags fethcing data from several different CDN’s is a bad idea (multiple DNS lookups).</li><li>Consumers spend on average 200EUR on their Android phones. The phones are not bad, but apps like Discourse perform very badly on them.</li><li>Even in good networks, phones can expect big latencies because the radio is usually turned off to conserve power, and needs to be powered up for the new request.</li><li>Being able to stream most of content in initial request increases the perf a lot. This means inline critical styles, inline images (i.e. content directly in src), etc. The story doesn’t tell how to do this in modern SPA’s most easily, but I bet we’ll hear more about that later.</li><li>Even the most horrible phone you can still buy (40 eur or something, can’t remember) can play cut the rope, but can’t load up Discourse at all.</li><li>Web apps are often bad, and we should feel bad for giving a negative impression on consumers (leading to consumer preference for native apps, which is not great if you are a web dev).</li></ul><h3>“Angular 2 Forms” by Kara Erickson</h3><p>Kara is the author of the Angular 2 forms API. She showed the ropes around the forms, and contrasted template driven forms (ok for simple stuff) and reactive forms (better for more complex stuff, bigger initial development time but simpler and more predictable in long term). Kara seemed to gather some kind of cult following in the conference due to her incredible typing speed and editor (WebStorm) acuity.</p><h3>“Connect your Angular app to any existing backend with GraphQL” by Uri Goldstein</h3><p>GraphQL was on table a lot, and it’s great to see it making inroads. Uri (not URI, *eh*) works with the Apollo GraphQL client, which is like Relay without React lock-in. Uri showed fast patterns on maintaining network-fetched application data with GraphQL, hooking it up to his demo Angular 2 application. He played around with the GraphiQL interactive query authoring tool, and it seemed like a breeze.</p><h3>“Universal Tooling” by Jeff Whelpley</h3><p>Jeff (of AngularAir &amp; Universal fame) was going through the still-unreleased features in Angular-CLI to enable building universal apps. Apparently they are also looking to enable testing straight in Node, without having to boot up Karma. Jeff also announced the “<a href="https://angularnation.org/">AngularNation</a>” community effort, which will grow to be a website where feedback and discussion on Angular 2 can happen. There will be curation, and some stuff could be cherry picked as feature requests to Angular 2 project itself. Right now it’s just a Medium blog though.</p><h3>General takeaways</h3><ul><li>The conference was a confident tour-de-force for Angular 2. It’s good and shipping. There was no React whataboutism or “it will be very hard to port my Angular 1 app” in the air.</li><li>Performance and optimization was a recurrent theme. Closure Compiler deserves a fresh look.</li><li>GraphQL is actually happening. Couldn’t be happier about this; if you know me, you’ll know that I’m no fan of the REST/HATEOAS/Roy Fielding trainwreck for web API’s. Doing the server side was not covered.</li><li>RxJS story is not complete yet. They will be working on that.</li><li>Exra from the sponsor booths: ag-Grid is a real company now, with paid developers, marketing and clients (esp. in finance shops). This is good news for those of us not completely happy with the other grids in the market.</li><li>Kara is a fast typist.</li><li>Further evolution of Angular 1 will be all about easing the porting to Angular 2. We could see stuff like backporting the Http service etc.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=96bfc790c7fa" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>