TS2688 with TypeScript, React Native, and MobX

To preserve my sanity if I should run into this again…. 

I created a React Native project, ejected it, and then converted it to use TypeScript. Things were going well until I started to use MobX. The following error occurred:

node_modules/mobx/lib/utils/utils.d.ts(1,23): error TS2688: Cannot find type definition file for 'node'.

Something as simple as:

import { observable } from "mobx";
may cause the error shown above. If you look at the utils.d.ts file mentioned in the TS2688 error line, you’ll see what’s causing the error:
/// <reference types="node" />
It seems like a harmless error and easily resolved. Usually when there are missing types, your first step should be to add them to your project. My first attempt was to add the @types/node to the project.
yarn add -D @types/node
Bzzt. That produces a whole new batch of errors due to duplicate definitions. There are quite a few classes and functions that are duplicates when React Native and Node declarations are both imported.
Apparently, this needs a stub for node so that the error can be bypassed (without changing or using other compiler switches like –skipLibCheck).
I created a new folder in the src tree called typings. In that folder, I created another folder, this time called node. And finally, in that folder, I created a nearly empty file called index.d.ts (the file contains a comment about why I created the file and a link to this blog post).
Folder structure
The project now compiles without issue. The declaration types that were needed by MobX are already included elsewhere, but the pesky reference directive forces the compiler to try to locate the types.

Flutter Demo application linking to BoardGameGeek.Com’s Hot Game List

I’ve built a slightly more interesting application using Flutter.  Using an XML feed from BoardGameGeek’s API, the application displays a list of the current hot games complete with thumbnail images.

Android Screen

Here‘s the code. I used a standard Flutter app template and also added a few packages to the project.

I’ve coded a substantial amount of Windows Presentation Foundation (WPF) and Silverlight code over the years. One of the concerns that often came up was the UI tree …, the more complex it was, the slower the app often was without lots of tricks. Using the new inspector for Flutter apps, I selected one of the images in the UI. Needless to say, there are a few objects created to represent the UI tree. In fact, I had trouble capturing the image for this blog post. :)


Flutter Nesting

I don’t have evidence that this generally will be a performance problem. Maybe with relatively simple mobile applications, a deep rich object based UI hierarchy won’t affect performance as much as it might in a desktop application of reasonable complexity. Regardless, it’s worth considering as you build a UI.

Back to what I built. When a user taps on a board game in the list, I’ve wired the code to call the _showGameItem below. I appreciate that there’s an easy way to navigate to a new page on the stack and show a UI, all within a single function. Of course, I could have split it into multiple builder functions if needed.

To register an event callback for the onTap, I’d tried finding a Widget that exposed it directly. I’m accustomed to elements having events (often bubbling events) that would have exposed something like onTap. However, with the exception of specialized widgets like Buttons for example, it’s not exposed on most Widgets (even those that have UI). So, at the outer layer of the items being shown in the ListView, I used a GestureDetector to capture the tap event:

I would have preferred that the Container to have the event available. Maybe it’s not as pure, but, meh. I’d like to reduce the noise of building a UI and adding yet another layer just to capture an event is a distraction.

Architectural elegance does not always lead to a framework that is easy or friendly.

While I wasn’t really concerned about performance of my application or the possible impact from hitting the BoardGameGeek API a few times, I used application storage to cache a copy of the XML data that’s retrieved from BoardGameGeek just to get some experience with the APIs. Further, I added code to store the next time the file can be updated to the SharedPreferences object instance (to prevent it from being updated too frequently). I liked the simple exception handling in Dart as it’s relatively low impact to handle a specific exception type without caring about the details by using the on clause (just by dropping the catch(e)).

I noticed that the exception handler can specify one or two parameters. The first is always the exception and the second is the stack trace (StackTrace).  I’m not sure why the stack trace isn’t part of the exception object though.

When the file is cached completely and successfully, the Widget state is updated, which triggers an application refresh, which is what happens on lines 29-32.

Had Flutter been an option in the earlier days of Android, it would have been a strong contender in the application building space, especially that it runs on Android and iOS. From reading some of the issues on Github, the general consensus is that the cross-platform Flutter competitor to beat is React Native. In fact, I’m surprised that it has taken Google this long to produce a potentially viable alternative to the Java Android development tools. I’d honestly thought they’d announce something several years ago (I’ve watched Google I/O for many years for the announcement).

If Android devices were upgraded more routinely (as are iOS devices), web technologies such as installed progressive web applications could be a serious contender and alternative for many application types. But, modern Android operating system versions are very slow to roll out (if ever) to the majority of devices.  Over half of Android devices are running Android 6.0 or earlier.

Android Developer Version Distribution

Until the Android OEM ecosystem delivers timely updates to all phones newer than 5 years, solutions like Flutter (and competitors) remain a potentially reasonable way to reach a large variety of devices without needing to update to recent OS releases. However, it may be that the hardware hosting older versions, such as 6.0/Marshmallow and earlier are not capable of adequately executing a modern app built with technology like is used by Flutter.

Continued concerns

I still find the syntax of building a UI to be cumbersome and frustrating for several reasons:

  1. Using code to describe the UI is not effective for me. I can’t as quickly look at a block of code and determine what the UI is likely to be. It’s just too noisy.
  2. I’m constantly frustrated by getting the right number of closing parentheses to match the open parentheses. Using the auto formatting tools of Android Studio for Dart doesn’t make it easier. There are 10 lines that are marking the closing of some block. I’ll add an example below of how messy it starts to look if they’re combined in a way that the auto formatter suggests.
  3. In fact, if it were easy, I’d want to lines to start with the Widget type rather than child: new WidgetName(. But, there’s not an obvious way to format the code that way as the named parameters (child) are needed to provide the widget instance.
  4. Layout is a mess of classes and initialization. The examples on the web site make general sense, but when I’ve tried to innovate on my own and understand how to build other UI patterns, I’ve struggled to find the right combination of Widget classes that represent a desired layout. I imagine that with practice I’d get better, but I also would likely create multiple stateless Widgets to make some of the common patterns I’d expect to use routinely.

Hulk Smash Layout

Does Flutter have a future? Would you want to build an app that you wanted to still be building on 3-4 years from now? As it’s still in Alpha form, I wouldn’t do anything but explore.

Then, there’s Dart. The strength of many development options for mobile and web development is the ability to concentrate on one programming language and have it work on client and server. With Flutter and Dart, if you don’t have a serverless-style architecture in place, you’ll need to use a second programming language. And that may limit its adoption. Of course, developers that work on multiple app platforms today have accepted this is just the price they have to pay, so maybe that’s not a big deal. If you’ve got a development shop that can have developers specialize, then this may be a non-issue entirely. For startups and very small teams, it’s a potential obstacle that must be considered.

 

Notes

If you try the code as I’ve put it on GitHub, you may encounter an error with a codec. This is actually a bug in the Flutter framework and apparently is fixed already and will be available generally at some point in a mainline branch. You’ll just need to rerun it.

Example of Auto Formatting

Note the parentheses on lines 20 and 21. That style causes me to just keep adding closing parentheses until the syntax is correct or the error is different. They’re very difficult to count.

Android Studio

Android Studio is an acquired taste from a theme and style perspective. With a few adjustments, it’s tolerable.

Android Studio Font and Color Settings

I’m not sure why Keywords in the Darcula theme are bright, bolded orange. While keywords are important, they’re unnecessarily vibrant, especially in code blocks describing the UI:

Bright Bold Orange Code Block

I turned off the bold minimally and changed the color of class names as an experiment … it’s better, but not right yet.

Android Studio with custom class name

Flutter.io First Impressions

I’ve been tinkering with Flutter.io for a few days now and wanted to document a few early impressions.

It uses the programming language Dart. I’d looked at a lot of Dart code when it was first announced, but hadn’t looked at it much since. I couldn’t see it gaining meaningful traction against the JavaScript juggernaut as a transpiled option (as it added too much overhead from the complaints I’d read) and there was zero evidence that any company besides Google was considering integrating it as a native option for Web pages. Without broad industry cross-browser support (from desktop to mobile as well), it seemed like a dead-end option that didn’t add measurable value. In some ways it was doomed to fail as it was trying to be a better JavaScript rather than rethinking the whole client development experience. It was just a new web programming language.

Originally, Dart’s messaging was broad and suggested that it was an ideal language for everywhere. That has changed since it’s original announcements to be focused on client development. But, that shift was recent and apparently connected with the announcement of Flutter.

From November 1, 2011:

Dart Language Home Page

 

to late February 2018:

Dart Home Page, 2018-02

Even as recent as May 2017, the Dart team was still considering server development as a potential platform target:

Dart home page, May 2018

It seems logical that the team would pivot to concentrate on a single target platform type, the “client.” Dart hadn’t gained substantial traction in server development or client development. While a recent video I’d watched suggested there were 70 million lines of Dart code on Github, I’m not sure who’s writing all that code and why. The dart-lang repository hosted on GitHub hasn’t seen a lot of “Star” love.

1500 Stars on Github

Compare those numbers to TypeScript for example:
31,301 Stars on Github
Nearly 30,000 more stars (and TypeScript was announced about a year after Dart).

I wouldn’t choose Dart for new development outside of Flutter. My initial impression is disappointment that the Flutter team is using Dart as it adds one more language to the client-side development smörgåsbord. I don’t know that the world needs another programming/UI toolkit lock-in option right now added to the buffet. I like variety and competition, so I’m all for that, but I also worry that limited adoption of frameworks leads to abandonment and frustrated developers. I can speculate why they choose Dart, especially as it’s staffed by Google developers, and I can see the appeal of the language, but….

I don’t need more programming languages right now in my solutions toolbox. It’s one more thing to learn and master. Since Flutter is also new, it has made the initial ramp-up time longer than I’d expected and wanted.  And because the language syntax is very familiar by design, it’s unfortunately likely that habits from other C-like and TypeScript-like will find their way into coding I do in Dart.

While the community at large apparently considers the Widget building syntax to be a strength of Flutter, I can’t say that I’m excited about it. It’s chatty and verbose. (And I haven’t been able to tell if the enthusiasm about the current syntax is just from the early adopters or fans, or it’s generally well liked). It absolutely doesn’t feel like it’s moving the needle when compared to all of the other GUI frameworks that have come before it. In fact, it reminds me of my earliest coding experiences using Turbo Vision. Yeah. Turbo Vision from Borland. (Wow — the past 20 years of IDEs and development tools originally from Borland has undergone an amazing number of ownership changes).

Turbo Vision Programming Guide

(Yes, it’s not really like that too much, but I had some flashbacks to my Turbo Pascal days).

Here’s a snippet of some code, written in Dart which represents a single item (more about this in a later post), with a thumbnail, a name, and a year published.

Of course, alternatives have been proposed, like a JSX-like syntax. This proposal brought out the best and worst of engineers of course. A few of the collaborators on Flutter were so dismissive of the idea I nearly stopped looking at Flutter.  As Flutter is in its early days, and backed by Google, I expect ideas are rationally considered and individuals to be treated with respect, even if there is disagreement. I’ve done years of WPF, Silverlight, and UWP development which used XAML. While there continue to be some rough spots in XAML, I appreciated the structured document for building a UI. I don’t know that I’d go in that direction for Flutter, but I don’t think describing complex user interfaces entirely in code is the best for its future viability, especially as it needs to compete with a variety of other frameworks and options.

Ignoring the syntax of how to describe a UI though for a moment, I’m still having trouble with wrapping my head around the idea that State actually renders a UI:

It’s the build method that returns the object hierarchy that describes the widget tree, not the class that subclasses StatefulWidget.  If you instead use a StatelessWidget, it builds its Widget hierarchy directly within the class. I can see how they arrived at this implementation, but it just feels inconsistent.

I like the async/await support in Dart. I do wish that I wouldn’t need to specifically declare the return type as Future<T>. The code has already signaled that it’s async, so if Future<T> could just be T, some code clutter would be eliminated.

AndroidStudio

The the code above, it’s great that the return value is automatically wrapped in a Future without any special code, but taking it a bit further would make Dart and Flutter more appealing.

I’ve been using TypeScript long enough that let and const functionality is second-nature. Unfortunately, Dart’s language is subtly different and I end up trying to use const where I meant to use finalThat’s my problem of course, but it’s just a gotcha. Const in Dart is for compile-time constants.

I’ve been generally pleased with using Android Studio with the Flutter plugin. It performs reasonably well, and it’s a good editor with lots of bells and whistles. The build/debug times are quite long, even for a basic app. It’s about 25-30 seconds for a build and deploy to an emulator. Thankfully, the plugin and Flutter both support hot reloading, so many changes to the code can be updated without needing to do a new build/deploy. While that’s very helpful, I’d like to see a significantly reduced build and deploy time.

In a market saturated with options for building cross-platform application UIs, it’s not clear how Flutter fits in. I’ve liked the experience enough that I’m going to build out a few simple apps and will show off more details in a later post of an app I’ve been tinkering with as I learn the platform and development environment. Flutter is in an “alpha” state right now, so a lot could change before it’s available in a final release (if it ever is). According to their Github repository, they have currently 86 issues open for their “beta” milestone. There’s no meaningful date associated with the transition though.

Mattress-Firm

How to make your too soft Tempur-pedic Bed comfortable

We’d suffered far too long. Our 2 year old Temper-pedic mattress was painful to use.

I couldn’t find a comfortable way to sleep anymore and was tired nearly every day and had too many aches and pains many mornings. My wife complained that her neck hurt frequently and that her shoulders and back were sore. As our Temper-pedic mattress was nearly $2500, we were reluctant to replace it so soon. But, we had to do something. I hated that bed and was dreading trying to sleep at night. The marketing by manufacturers suggests a memory foam mattress nearly to be the fix to every problem you have sleeping. Yeah, sorry. It’s not.

I’d done quite a bit of research and there were several schools of thought.

  1. Buy a new mattress. There’s no fix.
  2. Place something firm under the mattress.
  3. Buy a mattress topper of some type
  4. Crazy ideas…

As a last resort, buying a new mattress remained an option. However, not only did we not want to spend that amount of money again on another mattress, we were uncomfortable with throwing out a mattress that was so new. It hasn’t even developed the slightest hint of wear (there aren’t any sunken spots where we obviously sleep most frequently).

The second option didn’t make much sense given the density of the mattress. While I could see how it could potentially work for traditional box spring mattresses, our mattress didn’t require or need a base. Further, the base our bed rested on was pretty firm anyway. So, I didn’t see much reason to pursue that.

The challenge then was to buy a mattress topper. Was there something that was firm enough that it would mask the overly soft Tempur-pedic bed?

I read so many blogs and advice sites, with no clear answer. The general opinion was that a mattress topper could help, if you bought the right one and it was properly supported. In fact, some people bought toppers and then placed hard rubber mats underneath the topper to help provide a more solid foundation. As I was worried a bit about the off-gassing and smell of that solution, I looked for other options.

After extensive research, we settled on this:

Pure Green 100% Natural Latex Mattress Topper – Firm (3″ King Size)

The king sized topper arrived in a large box, folded once in half, rolled and protected in a thick plastic “bag.” We were careful to not damage the bag when removing the mattress topper in case we needed to return the topper. It did make removing the topper from the bag a bit more work than if I’d carefully sliced the bag open. Thankfully (according to the seller on Amazon), they do accept returns and offer to send a box to return the mattress topper if necessary.

Can I return the topper?
Yes!

So, after a few minutes on the floor, we hefted it onto the bed. It’s not lightweight, and as it’s extremely flexible, it was more awkward than we would have liked. I’d recommend folding it back in half so it’s easier to lift and move onto your bed. As you shouldn’t need to do this often, I wouldn’t be concerned about the one time lift. If you’re by yourself and trying to place a King sized topper, it may take a few more minutes and some grumbling. It apparently weighs about 65 pounds, so some amount of dragging it into place may be necessary.

Our sheets JUST accommodated the extra height. Just. If the topper had been 4″, the sheets wouldn’t have worked. The topper, while designed for a king was a bit “proud” of the size of the bed and was about 2″ total wider than it needed to be. I’m not sure if that’s normal, but it didn’t affect our sheet fit thankfully. Be prepared to potentially buy new taller sheets.

The first night was a welcome relief, even though the bed was noticeably more firm. We were both worried at first that the topper would still “sink” too much into the Tempur-pedic, but it doesn’t seem too. The next morning, we both felt far more rested and less sore than we had in 6 months. The second night, ahhh. Nice.

Some folks online have said it’s not “firm” enough. As firmness is subjective and personal, I can only say that it’s a comfortable firmness for us. If it were less firm, I’d suspect that it wouldn’t do much good. We’ll probably need to rotate the topper occasionally to prevent sunken/wear spots.

There was zero smell that we could notice both out of the packaging and when placed on the bed. Older reviews mentioned that the latex would crumble some. As ours is new, we haven’t experienced that. If it does, we’ll buy a simple cover for it. The topper is manufactured in many different sizes, from Twin to California King.

If you’re like us, suffering for buying a mattress that’s too soft and doesn’t offer enough support, I’d recommend the mattress topper (or something similar). Of course, it’s a bit risky to buy something like this sight unseen given the price, but as you shop around, make sure there’s a liberal return policy and be willing to return it if it doesn’t work out.

Two weeks later, our only regret is not buying it sooner.  

Other Information

Our current memory-foam Tempur-pedic mattress is of medium softness (we own the TEMPUR-Cloud Prima). I sleep in nearly every way possible, except flat on my back, and my wife sleeps mostly on her back.

An IKEA mattress topper was suggested in a number of forums. As we don’t have a nearby IKEA, we couldn’t evaluate the option in person. While it is an option that IKEA will sell online, the shipping/handling was extremely high to our location and most people said that it would still need another layer of very firm support under the topper. While overall the option may have been less expensive I suppose, it didn’t seem as promising as the option we purchased.

Quick demo of Go’s context.WithTimeout

To better understand Go’s context withTimeout functionality (and as a reference for myself), I’ve created this small self-contained demo. I didn’t find the published documentation’s example to be clear enough. The interesting part, coming from other programming languages and platforms, was that the WithTimeout function only was a signal that something happened. It doesn’t do anything when there’s a time out (like abort a goroutine or anything dramatic like that).

The essential pieces:

  1. Call WithTimeout passing the Background() context and specify the timeout (I’ve specified  3.2 seconds)
  2. Be a good citizen and defer the cancellation (to be sure that it’s called) and defer close the channel
  3. Start the go routine which waits for the Done channel
  4. When the Done is signaled, display the current time in seconds and what caused the signal
  5. The main app is waiting for the goroutine to end, so signal that.
  6. In the main function, the code sleeps and wakes emitting some time stamps to the console
  7. Depending on whether cancel is called, the goroutine signal may be one of two things.
    1. If cancel is not called prior to the second sleep in the code, the ctx.Err() returns
      <-ctx.Done():  context deadline exceeded
    2. If cancel however is called, the ctx.Err() returns:
      <-ctx.Done():  context canceled
  8. Then, the goroutine uses the channel to signal completion (wait<-true).

You can experiment with this sample here.

With cancel called (the line cancel() not commented out):

first sleep completed,  02.00
Timeout: 02.00
in <-ctx.Done():  context canceled
after second sleep done,  04.00

And, with // cancel() commented out:

first sleep completed,  02.00
Timeout: 03.20
in <-ctx.Done():  context deadline exceeded
after second sleep done,  04.00

Hopefully this helps someone besides me.