A Web Page for Reformatting JSON Text, using AngularJS

A little over a year ago, I published A Web Page for Reformatting JSON Text, which is a simple web page for pretty-printing JSON data. I'm now learning AngularJS, so as an exercise I reimplemented the page using Angular rather than the original's jQuery.

This version is a little nicer than the original in the following ways:

  • You can type or paste text into the top box and the formatted JSON immediately appears in the lower box. There is no longer a need to press a Format button because Angular's data-binding mechanism takes care of automatically updating the output whenever the input changes. (This is possible with jQuery too, but takes more work.)
  • You can control the indentation width of the formatted JSON.
  • When the input is not valid JSON, the output panel changes its background color to red when displaying the error message.

Here it is: JSON Formatter with AngularJS

Short link: http://bit.ly/formatjson

You can look at the full source here: Gist

or as a fiddle: http://jsfiddle.net/oldmankris/qK9LK/

If don't know anything about AngularJS, but are curious about it, look at the source and note the following:

  • The magic of Angular comes from the ng- attributes attached to HTML elements. There is no need for a separate template language or explicit DOM manipulation.
  • The ng-app attribute attached to the html element sets up the module that contains our app's code.
  • The ng-controller attribute attached to the div element defines which controller function to use.
  • The ng-model attribute attached to the first textarea element binds its content to the inputText variable
  • The ng-bind attribute attached to the second textarea element binds its content to the value of the outputText variable, and the ng-class attribute binds its CSS class to the value of the outputClass variable.
  • The ng-options and ng-model directives on the select element bind it to the indentOptions and selectedIndentOption variable.
  • In the controller code, we set initial values for the inputText, indentOptions, and selectedInputOption variables, and then use $scope.$watch() to update the values of outputText and outputClass whenever any of the inputs change.

OS X Server Local Websites for Web Developers

OS X Server is now available free of charge for members of Apple's iOS Developer Program, so I have it installed on most of my machines. Unfortunately, having OS X Server installed complicates the use of the built-in local Apache web server which I use for web development. I've figured out how to make things work the way I like, and I have written this article so that I can find the information again when I need it. Maybe it will help somebody else too.

Zenburn for Xamarin Studio

I've been playing around with Xamarin. Its IDE, Xamarin Studio, comes with a bunch of (IMHO) terrible color schemes, so I ported Zenburn to the Xamarin format.

You can find my Zenburn for Xamarin theme here: https://gist.github.com/kristopherjohnson/784360f9676b59766678

To use it, download the .json file, open Xamarin Studio, go to Preferences > Syntax Highlighting, click the Add button, and select the file.

It's not a complete rendition of Zenburn. I've only defined the colors that are used in C# and F# code, and haven't bothered with all of the subtle color distinctions between different varieties of syntax elements.

2014 Publix Georgia Marathon

Kris with Medal

I finished a freaking marathon!

I ran the 2014 Publix Georgia Marathon in Atlanta on March 23. I got up at 4:00 AM, drove to the MARTA train station, and took the train to Centennial Park, where the race started and finished.

The weather was good for running a marathon. Temperatures were in the 50's, and the sky was covered with clouds. The forecast called for rain, but aside from a few sprinkles halfway through the race, we stayed dry.

I have previously run two half marathons with times around 2:10, so I was expecting my marathon time to be somewhere between four-and-a-half and five hours.

That was wildly optimistic.

The Georgia Marathon course is very hilly. The course I run when training has more hills than the average marathon course, I think, but it didn’t prepare me for this course.

For the first ten miles, I kept to my goal pace of ten and a half minutes per mile. After mile 12, I had to walk up most of the uphill stretches, and there were a lot of uphill stretches. After mile 21, I couldn’t even run on the downhill stretches anymore. My legs would cramp whenever I tried to run. I wasn’t even sure I’d be able to walk those last five miles.

My final time was 5:41, about an hour longer than I expected. I think I did everything right in terms of preparation, nutrition, hydration, and pacing. I just hadn’t built up the endurance to run 26 miles of hills.

But hey, I finished a freaking marathon.

My FitBit says I took over 54,000 steps (including steps walking to/from the marathon). I suspect that will be my daily step record for a while.

On mile 20, some spectators were handing out cups with a brownish liquid. I assumed it was iced tea, but was delighted to find that it was cold beer. I’d like to nominate those people for the Presidential Medal of Freedom.

Action photos available here: Facebook photo album

Setting Up ArcGIS Runtime SDK for iOS for Xcode Bot

I am working on an iPad app that uses the ArcGIS Runtime SDK for iOS. Esri provides an easy-to-use installer and instructions for setting up the SDK so that it can be used with Xcode.

The installer puts the SDK files in the user’s home directory, and the setup guide recommends using paths like $(HOME)/Library/SDKs/ArcGIS/iOS/ in Xcode projects to find the framework’s headers and libraries. This works fine as long as one is using Xcode as a user who has installed the SDK. However, it causes problems if one wants to set up an Xcode bot to automatically build and test the app. The Xcode service that runs bots executes under the _teamsserver user account, and by default that user’s home directory does not exist, and you can’t log in as that user to run the SDK installer. So attempts to create a bot to build the app just result in “ArcGIS.h not found” compilation errors.

After I bit of Googling and experimentation, I came up with a solution:

  1. Install the SDK in my user account (or another normal account), following Esri’s installer and instructions.
  2. Make my ~/Library directory world-readable:
    chmod 755 ~/Library
  3. Create the /var/teamsserver home directory for the _teamsserver user:
    sudo mkdir /var/teamsserver
  4. Create the /var/teamsserver/Library directory for the _teamsserver user:
    sudo mkdir /var/teamsserver/Library
  5. Set _teamsserver as the owner of the directories:
    sudo chown -R _teamsserver:_teamsserver /var/teamsserver/
  6. Set permissions on the directories:
    sudo chmod -R 770 /var/teamsserver/
  7. Create a symbolic link to the SDK installation:
    sudo ln -s ~/Library/SDKs /var/teamsserver/Library/SDKs

This works. It could be argued that it would be better to set up the symbolic links in some shared location (/Library, /usr/local, etc.) and then use a full path in the Xcode project to find them, but I prefer this solution because it doesn’t require any extra steps for developers who don’t need to set up a bot.


Another annual State of the Kris message:

The biggest change for my family this year was moving from our little mountain cabin in Dahlonega to a house in Cumming. This puts us closer to the schools where Pebble teaches and where Bailey learns. Instead of spending two hours commuting per day, we now spend about 30 minutes.

I used to joke that we should just move to exit 14, since that’s where we spent our weekends shopping. Now we’re here.

Our five dogs love the big fenced-in wooded backyard. They get to chase deer once in a while. (I don't know what a Yorkshire Terrier would do if it caught a deer, but I'm not worried about that happening.)

I ran two half marathons this year, and I’m preparing to run a marathon in March. I’ll probably also try to run the Atlanta Marathon in October. After that, I suspect I will be finished with marathons, but will keep running twenty or thirty miles per week. I enjoy running, and like being in better shape than I have been for the past couple decades.

Pebble is now working at North Forsyth High School, teaching courses in forensics and agricultural science. She seems less stressed-out than she did while working at the middle school.

Bailey is really enjoying the marching band. His band went to a competition in New York, and they took third place. The band will be going to London in December.

I usually make a list of goals for each year. However, I rarely consult that list after making it, so I’m not going to bother this year. I hope to run two marathons, and I hope to learn to play piano, but I really just want to enjoy life in our new home.

Garmin Forerunner 110 Blank Screen

I recently purchased a Garmin Forerunner 110 GPS watch to track my runs. I've been happy with it, but today when I plugged it into my computer after a run, the watch screen flashed "Saving activity" and then went blank. The watch was dead after that.

It had been fully charged before my run, so I was pretty sure it wasn't just out of juice. The instructions provided with the watch weren't helpful.

This blank-screen issue appears to be a common problem. The Forerunner 110 Blank Screen (Dead) thread in the Garmin forums has over 100 entries. You can browse that thread for details, but here is a summary of the suggested fixes:

  • Hold down the Light, Start/Stop, and Lap/Reset buttons for about 30 seconds. (This worked for me.)
  • Hold down all four buttons for about 7 seconds. (Didn't work for me.)
  • Hold down the Light button for about 6 seconds. (Didn't work for me.)
  • Hold down the "Power" button while plugging it into the computer. (My watch doesn't have a button labeled "Power". I tried this with the Light button, and with the Page/Menu button, but neither worked.)
  • Plug it into a different USB port. (Didn't work for me.)
  • Just leave it plugged in for a few days, and eventually it will spring back to life.
  • Rub the contacts with a pencil eraser.
  • Attach the USB clip, but don't attach the clip to a USB port, and hold the Light button for 6 seconds.
  • Check whether there is a firmware update available.
  • Try a master reset.
  • Contact Garmin Customer Support.
  • Take the watch back to where you bought it for replacement/refund.

After I got it working, i checked for a firmware update, and indeed there was a new firmware version available for the Forerunner 110. This is in the release notes:

Changes from version 2.60 to version 2.70:

Fixed an issue where the device could display a blank screen while connected to the charger.

I installed the update. I'll have to wait to see whether the problem recurs.

Update 2014-01-23: The screen went blank again. Hold down the Light, Start/Stop, and Lap/Reset buttons got it working.

Update 2014-03-09: Blank again, and the above remedies weren't working. The recharging display did appear when I connect it to USB, but it wouldn't do anything when disconnected. I let it sit disconnected for a few hours, and it sprung to life.

The Running Thing

A year ago, I was proud of running a 10K. Since then, I've run two half marathons, and I am currently preparing to run the 2014 Publix Georgia Marathon in March.

Here are some things I've learned along the way:

  • Having a training plan is important. Just going out and running a few miles when you feel like it doesn't get you anywhere. You need to steadily build up your mileage. I can personally recommend the Couch-to-5K plan for beginners, and I am currently in week 7 of Hal Higdon's novice marathon training program, which is working well so far. Put your workouts on your calendar, and treat them like any other important appointment.
  • Rest is important. All the training plans have rest days and "easy weeks" for good reasons. Don't push yourself too far too fast, or you will just hurt yourself.
  • Stretching is important. I used to roll my eyes at the people who seemed to spend more time with their stretching rituals than actually running, but after trying it myself, I found it was easier to run and I was less sore afterwards.
  • Shoes are important. When my runs started getting into the five- and six-mile range, I was getting shin splints and other pains. Then I bought some new shoes, and those problems went away. My current favorite shoe is the Asics GEL-Cumulus 15, but you need to try on shoes yourself to find what works for you. I have two pairs of shoes, which I alternate (so that each pair gets 48 hours to dry out and re-spongify between uses), and I replace them after 200-300 miles.
  • Gadgets are fun. The geek in me likes having instrumentation. Using a FitBit or a GPS-tracking device to record runs was helpful in sticking to my training plan, because even when I didn't feel like running, I wanted my numbers to be right. I used a couple of smartphone-based run-tracker apps early in my experience, but stopped using them when I got tired of carrying a phone-sized device when running (particularly an Android phone-sized device). I now have a Garmin Forerunner 110 watch that records my time, distance, and heart rate for each run.
  • Races are fun. You may have to do all or most of your running by yourself, but entering a real race lets you share the experience with hundreds or thousands of other people. It's a festive atmosphere, and everyone is encouraging and supportive.

Finally, almost anyone can do this. I'm almost 47 years old, and have led a sedentary lifestyle for the last 30 years, but I will be running my first marathon in a few months. Obviously, if you have serious health problems or physical limitations, you might not be able to do it, but if you're reasonably healthy, it's just a matter of putting in the time.

Setting Up Windows, My Way

This is a companion piece to my Setting Up a New Mac, My Way entry. Thankfully, I haven't had to use Windows much in the past couple of years, but when I do have to set up a Windows machine for some task that requires it, I want to have a list of things to do to minimize the pain.

(This is a work in progress. It will evolve every time I go through the setup process, and every time I have to work around some annoying Windows limitation.)

  1. Install/reinstall Windows. (The remaining steps assume the version is Windows 8.1 Pro x64, and it is running in VMWare on a Mac.)
  2. In the Windows 8 start screen, remove everything except Desktop.
  3. In Desktop, right-click the taskbar, choose Properties, select the Navigation tab, and check the When I sign in or close all apps on a screen, go to the desktop instead of Start box and the Show the Apps view automatically when I go to Start button.
  4. In Settings (or Control Panel or wherever Microsoft puts these things this year) make these changes:
    • Ensure the Location is United States and English (United States) is the preferred language.
    • Enable automatic Windows updates.
    • Change the desktop background to a solid color.
    • Enable these desktop icons:
      • Computer
      • Network
      • Recycle Bin
    • Disable the screen saver and Turn off the display power option
    • Uncheck Hide extensions for known file types
    • Turn these Windows features on:
      • Internet Information Services (leave IIS 6 Management Compatibility off)
      • Telnet Client
  5. Install these applications:
  6. Start Powershell
    • Pin Powershell to the taskbar
    • Type this command to create the profile directory and file:
      new-item -path $profile -type file -force
    • Type this command to copy my profile to this computer:
      cp ~/Dropbox/windows/powershell_profile.ps1 $profile
    • Run Powershell as Administrator and run this command:
      set-executionpolicy -executionpolicy remotesigned
    • Restart Powershell (with the new profile)
  7. ... (to be continued) ...

The Easiest Programming Bug I Spent Way Too Much Time Trying to Solve

I ran across a question on Quora: What's the easiest programming bug you spent way too much time trying to solve?.

Here is my answer to that question. Some time during my first few years of programming, I wrote code similar to this little snippet and expected it to print "FOO", but instead it prints "None of the above". It is written in C, but should be comprehensible to anyone who knows a language with similar syntax (C++, Java, JavaScript, C#, etc.). It took me about a half day of staring and single-stepping in a debugger to figure out what was wrong. When I looked at the disassembly listing, I was convinced I'd found a bug in the C compiler. Maybe you can figure it out faster than I could.

#include <stdio.h>

int main(int argc, char *argv[])
    const int FOO = 1;
    const int BAR = 2;

    int n = FOO;

    switch (n)


            printf("None of the above");

    return 0;
Syndicate content