HTML5, CSS3, jQuery, JSON, Responsive Design...

Your code’s bug-free, or maybe not. Don’t trust Angular to tell you either way!

Michael Brown  September 28 2018 04:27:03 PM
My article on Medium.

TL:DR

If you don’t know what you’re doing with Angular, it may have a nasty surprise up its sleeve as you put your code into Production.  Angular's AoT (Ahead of Time) compilation mode, which is what the Angular Team tells you that you should be aiming to use for your Production builds, will flag errors in your code that its default JIT (Just in Time) mode doesn't!!!


Your code’s bug-free, or maybe not. Don’t trust Angular to tell you either way!

Running node/npm scripts sequentially on Windows

Michael Brown  May 5 2018 10:44:06 PM
Note: this same article also published on Medium yesterday.


So this is how I’ve traditionally been running node/npm scripts in my package.json file:

"scripts": {
"testRun": "node ./runtest.js && node ./runreports.js",

So running npm run testRun or yarn testRun will run the runtest.js script followed by the runreport.js script…sometimes! The catch is that the && part of this formulation is actually a Boolean logical AND. Which means if the first script returns an error code, such as Exit code (1) it evaluates to false and so the second script won’t run at all.

So I tried changing it from a logical AND to a logical OR, like so:

"scripts": {
"testRun": "node ./runtest.js || node ./runreports.js",

Now my second script runs when the first one errors, but it only runs if that’s the case. If the first script doesn’t return an error then the second one doesn’t run now; not much of an improvement!

Googling around, it seems that a semi-colon is the correct syntax for the second script to run irrespective of what the first one does, e.g:

"scripts”": {
"testRun": "node ./runtest.js; node ./runreports.js",

Great! Or it is if you’re running a unix-style OS such as Mac OS X or Linux. Unfortunately, I was using Windows due to my having committed terrible sins in a former life. Sadly, the semi-colon syntax just won’t work on Windows, because it’s, well…Windows. (Note: I was using the Git Bash shell on Windows 7. I understand that Windows 10 has a proper bash shell of some sort, so maybe the semi-colon syntax does work there.)

I thought about it some more and it occurred to me that because it’s Boolean logic problem, then there ought to be some kind of Boolean logic solution. Indeed, there was!

Now in boolean logic something OR true always results in true, e.g:

true OR true = true
true OR false = true
false OR true = true

Applying that logic to my package.json script, I came up with this:

"scripts": {
testRun: "(node ./runtest.js || true) && node ./runreports.js",

By wrapping the first script call with in some brackets and Boolean ORing it with a true, the result of that bracketed section must always be true. Now my runreports.js script will run no matter what the runtest.js script does.


Further Reading:

https://github.com/npm/npm/issues/4040

(Includes a comment from me, offering the solution above. Strangely, nobody there has recognised my genius thus far, but it’s surely only a matter of time!)

Develop React Native apps on a Chromebook

Michael Brown  October 22 2017 09:08:14 PM
Surley it's not possible to develop Android and iOS apps using React-Native on a Chromebook, right?  Well, it is!  Kind of...if you cheat a bit!

First off, you'll need to enable Developer Mode on your Chromebook and then install a full Linux desktop environment, either as a dual boot or as a crouton (allows Chrome and Linux to run side by side).  See https://github.com/dnschneid/crouton for instructions.

Next, you'll need to install Node and NPM in your Linux environment.  When you've done that, you can install the Create React Native Application (which I'll abbreviate crna from here on in) tool via NPM.  See here for instructions on how to do that: https://facebook.github.io/react-native/docs/getting-started.html

Once you have a crna app all set up, you'll be able to have it appear on your iPhone or Android phone via a mobile app called Expo, which you'll need to download from your respective app store.  Your phone will need to be on the same wifi network that your Chromebook is on in order for this to work though.

There's one more important step for this all to work on a Chromebook though: you'll have to open the Chromebook's firewall settings to allow the two ports that Expo needs to work.  These are ports 19000 and 19001.  Here's how to do that:

Opening Chromebook Firewall Ports
  1. On your Chromebook, open Crosh tab (Ctrl->Alt->t)
  2. Type `shell` at the Crosh prompt
  3. Enter following two lines at the prompt
sudo iptables -A INPUT -i wlan0 -p tcp --dport 19000 -m state --state NEW,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -i wlan0 -p tcp --dport 19001 -m state --state NEW,ESTABLISHED -j ACCEPT


That should have opened the two ports on your Chromebook firewall.  Note: these settings are not sticky.  The next time you restart your Chromebook, they'll be forgotten.  (This is actually a good thing, security wise.)   You'll just need to enter them again before starting your Linux crouton.

Now in your Linux crouton, kick off your crna bundle within it, e.g. `yarn start`, then try to connect via your phone’s Expo client (e.g. by scanning the code).

You may get a red screen, saying “Could not connect to development server” at this point.  If so, check the console on your Linux crouton and see if it’s finished building the JavaScript bundle yet.  Chances are that this will take a minute or two, unless you have a super new Chromebook Pixel!  Most Chromebook's processors won't have enough grunt to finish the compiling task that quickly, so you just need to wait a bit.  If crna is still building the bundle, wait for it to finish and then hit the reload link on your phone’s screen.


Obviously, this only gets you so far with development.  You're still limited to using the Expo app on your mobile device.  If you want to check it out natively on a device, then you have to eject from the crna environment.  You'll then need a Mac to put your iOS directly onto your iPhone/iPad, and to roll it out to the App Store.


Getting npm-check-updates to update global packages

Michael Brown  August 19 2017 09:34:25 PM
I often use the npm-check-updates package to check the whether my npm packages are up to date.  Particularly, my globally installed npm packages, such as...well, npm-check-updates itself!!!

It does have one rather annoying limitation though: -u option, which forces the packages to upgrade, only works with locally installed (i.e. at a project level) packages.  It won't work for your global packages.  So if you issue this command in your terminal (NB: ncu is an alias to npm-check-updates):

ncu -g -u


you'll see this error: ncu cannot upgrade global packages. Run npm install -g [package] to update a global package.  This is a pain, because the npm install -g command requires you specify the packages' names, and there might be a few of these.  For example, when I just ran ncu-g on my home Mac, it flagged the following packages as out of date:

create-react-app         1.3.3  →  1.4.0
create-react-native-app  0.0.6  →  1.0.0
eslint                   4.2.0  →  4.5.0
eslint-plugin-react      7.1.0  →  7.2.1
jsdoc                    3.4.3  →  3.5.4
npm                      5.0.3  →  5.3.0
prettier                 1.5.2  →  1.5.3


To update them all, I would have to type out npm install -g followed by the full list of the packages' names.  That's a lot of typing and/or copying and pasting to get the package names that I need.  So I Googled around to see if there was a way of formatting ncu's output to produce a more update friendly list.  This is the command that I found (sorry, I can't remember where now!):

ncu -g | awk '{print $1}' | paste -sd " " -


Issuing the above command gave me straightforward list of packages to update, like so:

"create-react-app create-react-native-app eslint eslint-plugin-react jsdoc npm prettier"

All I need to do is still an npm install -g in front of that string, and I'm away.

It's not a particularly easy command to remember, so you may want to put it in a script and run it from there.



    Random User Generator

    Michael Brown  July 16 2017 02:19:03 AM
    Hey, we all need one of these at some point in our Development careers!!

    The Random User Generator is, to quote their blurb: "A free, open-source API for generating random user data. Like Lorem Ipsum, but for people".  Just make an Ajax call to their API, and back will come a list of random users in JSON format (XML, CSV, or YAML).

    I came across this handy resource while checking out Spencer Carli's React Native Flatlist Demo on Github.  Here's a screenshot of that running in the iOS Simulator.

    Image:Random User Generator
    The data shown here is being pulled from the Random User Generator by an Ajax call.

    Hide the ***** footer on Medium.com posts!!

    Michael Brown  March 14 2017 01:47:38 AM
    I'm a big fan of the Medium publishing platform, but hate the way that it (and its various offshoots) display a fixed footer bar.   You know, the one that says "never miss an update from [whoever]", and that has a *Get Updates* button on it?    Yeah, guys, I've got that now.  So can I please close the darned thing and get some of my screen real estate back?  It seems not; Medium doesn't give you a way of doing that.


    Add Footer Close Button Extension

    So, I put together the Add Footer Close Button extension for Google Chrome.  It adds a button that hides that footer bar whenever it detects one.  That's all it does.  There's no options.

    It currently works on medium.com itself, and also hackernoon.com.  I'll add more offshoot sites as I come across them.  (It's just a matter of updating a permissions file.)



    Medium.com footer showing my close button

    React without build steps - Babel Standalone

    Michael Brown  January 19 2017 02:00:05 PM
    When I got started with React, over two years ago now, we had the JSX compiler tools.  All you had to do was load this JavaScript library into your HTML file, along with the React JavaScript library itself, of course, and you were done.  All of the React transpilation took place on the fly, within the browser itself.  Easy!

    I don't know what I'd have done if I'd been told that to start with React you need to install Node and NPM, then spend two hours fiddling about with your Webpack config file before you can write a line of your application code.  Something tells me though that I would not have had a positive reaction!  Unfortunately, that's largely what new developers are told to do now, since Facebook deprecated the JSX Tools in favour of Babel, and then the latter dropped their own in-browser transpilation tool (browser.js) in Babel 6.

    Fortunately, help is at hand in the shape of Babel Standalone.  To set it up, you simply add the babel.js (or babel.min.js) library to your HTML as a script tag, just after your main React and ReactDom script libraries.  Then, when loading your own JavaScript library (see simple-list.jsx in the code below) you set it type to "text/babel", then add any transpilations in the script tag's data-presets property.

    That's it; you're done!!:
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <title>babel-standalone Hello World example</title>
    </head>
    <body>

    <div id="main"></div>
    <script src="//cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>

    <script type="text/babel" data-presets="es2015, react, stage-2" src="js/simple-list.jsx"></script>
    </body>
    </html>



    Here's the contents of that simple-list.jsx file:
    const MyListElement = ({ listElement }) => (
    <li>{listElement}</li>
    );

    class MyList extends React.Component {
    render() {
    const { listArray } = this.props;
    const list = listArray.map((member) => {
    return <MyListElement listElement={member} />;
    });
    return(
      <div>
              <h2>Man in the High Castle Characters</h2>
              <ul>{ list }</ul>
      </div>
      );
    }
    }

    var myObj = window.myObj || {};
    myObj.listArray = ["Joe Blake", "Juliana Crane", "John Smith", "Frank Fink"];
    myObj.title;

    ReactDOM.render(
    <MyList
          listArray={myObj.listArray}
          title={myObj.title} />,
    document.getElementById("main")
    );


    It's a very simple app, which just displays a list of characters from Amazon's superb adaptation of Philip K Dick's The Man in the High Castle.  I've implemented two React components here: MyListElement as a function component, and MyList as a full ES6 class.  (I know that  both could have been implemented as function components, since they don't require any React life cycle hooks, but I wanted to show how Babel Standalone handles both component types.)  Demo here.

    You don't get module bundling/loading, of course, because Babel is not a module loader; you'll need Webpack or Browserify for that.  So you'll have to manage the script tag order yourself, and that's a pain.  But for getting devs started, that's not a show stopper in my book.

    Angular Release Candidate 5 - "major breaking changes"???

    Michael Brown  August 31 2016 05:13:55 AM
    Who’d be an AngularJS Developer?  Well, quite a lot of people if the stats are to be believed!  But oh Lordie, they really seem to be having a really rough time it with the upgrade to Angular 2.

    I've just listened to a recent Adventures in Angular podcast, entitled Angular RC5 and Beyond.  I’m not much fan of a fan of Angular, as you can probably tell, but I like to keep up with it anyway.  If for nothing else, it’s good to have reasons to show people/bosses that moving to Angular would be a truly terrible idea.  The Angular 2 rollout is giving me plenty of those!

    Of Release Candidates

    Anyway, RC5 refers to Angular Release Candidate 5.  "Aha", I thought; "they must be pretty close to release if they're on a fifth Release Candidate!"  However, I was disabused of this thought within the first few minutes, in which we’re told that Release Candidate 5 of Angular 2 contains “major breaking changes from release candidate 4”.

    Say what?  Major breaking changes in Release Candidate?  Thankfully, a couple of Google people are on hand to explain that in GoogleLand, things work a little differently.  A Release Candidate isn't a candidate to be release, as in the gold release; you know, how the term is applied by just about every other software company in the world.  No, it seems that for Google, Release Candidates are actually the first serious test releases geared towards public consumption.   Alphas and betas are mainly for internal testing, within Google only.  Angular 1 had seven Release Candidates, apparently.   Well, that's one approach, I suppose.

    There's a telling moment about half way through the podcast.  As one of the Google guys is detailing change after change in RC5, the podcast host pauses proceedings to ask one of the other participants why he hasn’t spoken much yet.  “Oh I’m just sitting here all grumpy, thinking of all the code I have to change...across hundreds of projects”, comes the reply.  Quite so.  And I don't think he was referring to Angular 1 code, either.


    NG Modules

    One of the big new things in RC5, apparently, NG Modules.  These are a way of breaking up your application in some more manageable fragments or components.  (So like React has had from the get go then.)  It seems that Angular 1 had some kind of modules thingy in it too.  These were originally removed for Angular 2, but they’re back now.   Only they’re not quite the same as they were in Angular 1, but "it helps if you think of them that way”.


    Webpack

    Almost as an afterthought, the Google guy drops another bombshell during the podcast's closing moments:  "did I mention that Angular 2 is now moving from SystemJS to Webpack?", he asks, laughing at what I took to be a joke, at first.  But no, he was serious: they really are moving to Webpack.  That may be all to the good, because Webpack rocks, IMHO.  But really, they want to be making a change like that in the fifth Release Candidate?  (Oh, I forgot; they're not really really Release Candidates, are they!)


         

    Goodbye, Chromebook, hello...Chromebook!

    Michael Brown  August 21 2016 12:21:34 AM
    It was my birthday last week.  One of my treats was a brand-new Toshiba Chromebook 2, bought to replace my aging Samsung model.

    The latter has slowed down to the point of being barely useful.  To be honest, it was probably underspecced when I bought it three years ago, having an ARM processor and only two Gig of RAM.  But the truth is that Intel processors at the time simply could not mach the battery life of the ARM processors:  the Samsung could give me over 8 hours of battery, which I'd never seen a laptop before!

    However, that ARM processor and also came with some limitations, which I hadn’t appreciated when I bought it.  For one thing, some Chrome Apps didn't even run on the ARM version of the Chromebook; they would only run on Intel versions, which was something of disappointment.  Maybe that’s less of a problem today.

    Full Linux Install

    Another problem was with the full Linux installation that I’d always intended to put on any Chromebook that I bought.  (With a Crouton-based install, you can switch instantaneously between ChromeOS and a full Linux install, which is a pretty neat trick!)  What I hadn’t realised though was that ARM versions of a some Linux packages simply aren’t available.  Most of the biggies are present and correct, e.g. Chrome, Firefox, LibreOffice, Citrix Receiver, GIMP, as well as developer packages, such as Git, Node/npm and various web servers.  But the killer was that there’s no SublimeText, boo hoo!  SublimeText maybe cross-platform, but it’s not Open Source, and its makers have showed zero interest in making an ARM-compatible version so far.  Sadly, I was never able to find a truly satisfactory replacement for that one.  I finally settled on the Chrome-based Caret editor, which does a half decent job, but it’s no SublimeText.


    The New Toshiba Chromebook 2

    Intel had to raise its game to respond on the battery life front, and give the Devil its due, that’s exactly what Intel did.  Battery life is now on a par with the ARMs, but with the benefit of extra power and also that Linux package compatibility.  For example, here's Sublime Text running in an XFCE-based Linux installation, in a Chrome window on my new Toshiba Chromebook:

    SublimeText on a Chromebook


    Other benefits of the Toshiba over the Samsung:
    • More powerful (Intel processor & double the RAM) so much faster performance
    • Much better screen: full HD 1920x1080 vs 1366x768 on the Samsung
    • Amazon.com delivers to Australia!!  And likely to other countries too.  (Good luck finding any decent Chromebooks actually on sale in Australia!)

    Local Storge

    Local SSD storage is the same on both models: a disappointing 16Gig.  You'll often hear ChromeOS aficionados telling you that local storage doesn't matter "cos' on a Chromebook you do everything in the cloud".  IMHO, that's a bunch of crap.  Local storage is important on a Chromebook too, especially if you have that full Linux install eating into it!!

    Now both of my models do come with an SD card slot, which allows me to boost that storage space significantly, and at no great cost.  But it's the Toshiba that shines here too, as you can see from the two photos below:

    Samsung Chromebook with SD CardToshiba Chromebook 2 with SD Card

    In both of these photos, the SD card is pushed in to its operational position, i.e., that's as far in as it will go.  See how far it sticks out on the Samsung?  What's the chances of my throwing that in my bag and then retrieving it a few hours later with the card still in one piece?  Not high, and that's why I never do it.  It sounds like a small thing, I know, but it's a royal pain the rear to fish around for the SD card in my bag whenever I need to use it.  With the new Tosh, the SD card sits absolutely flush with the edge of the case, so I can leave it there all the time, giving me a permanent 48 Gig of storage!!


    That Other OS

    The cost of this new baby?  $300 US on Amazon.com, which translated to just over $400 Oz, including postage.

    At which point I have little doubt that somebody is waiting to tell me "but for that kind of money you could have got a proper laptop that runs Windows apps".  But as you've probably worked out by now, I already know that.  And if I'd wanted to get a Windows laptop, then I would have got one.   The thing is that I don't like Windows much.  I don't like the way it works (or doesn't work), and most of the dev tools that I now live and breath don't work natively on Windows.  (Although there is, apparently, a native Bash terminal coming in Windows 10 at some point, courtesy of Canonical.)

    And what kind of Windows apps would a $400 Oz machine even be able run?  Microsoft Office?  It might run; as in it might actually start up.  Adobe Photoshop?  Ditto.  And how about all those Windows games?  Well, I suppose you might coax the new Doom into a decent frame rate, as long as you were prepared to compromise a little on the graphics!

    Doom (circa 1993)

    Domino server up time: eat this, Microsoft!

    Michael Brown  August 19 2016 02:46:25 AM
    There are some things that we just take for granted.

    I have this Domino server in the cloud, on Amazon Web Services.  It just occurred to me that I hadn't updated the Amazon Linux that it's running on for a while now.  So I logged in to check it out and I was right: it has been a while.  517 days, in fact!

    That's 1.42 years.

    Or one year and five months, or thereabouts.
    Domino server uptime
    In fact, it would likely have been a lot longer of that, if I hadn't take it down to upgrade it to Domino 9.0.1 in the first place.

    You know what?  I think I'm just going to leave it as is, and see how long it goes for...

    About