Tuesday, December 27, 2022

Map marker clusters and more user-friendly UI changes!

A big big thank you to open source developer Leigh Halladay, who published this useSupercluster hook for React:

use-supercluster npm package

use-supercluster Github page

I had been wanting to do map marker clustering using Mapbox and React, but hadn't found a solution until I stumbled on Leigh's library, described here.

This finally allowed me to cluster markers together, allowing me to publish sportsmap.world with a much friendlier interface for mobile users.  I've made additional changes to make the site more smartphone and mobile friendly, as that's the primary experience for most people browsing the web these days!

More UI upgrades since November:

- A better mobile calendar experience, including a dropdown calendar widget to allow you to select a date range, rather than relying on the double-date slider (which is still present for wider screen).

- A filter-by-sport widget, to remove specific sport pins from the map.

- Fast load times & optimized queries, plus a loading spinner while the initial query is in progress

Tuesday, October 4, 2022

Navigating the (React x Google Maps) Wild West

I wanted to try Google Maps in my React front-end, and figured that probably someone has written a React wrapper for Google Maps, or perhaps Google itself had taken it on at some point.

Here are some open-source packages that show up in an npm search:

  • react-google-maps, last updated five years ago but still gets 150k downloads/day.
  • @react-google-maps/api, a "complete re-write of the (sadly unmaintained) react-google-maps"
  • google-map-react 
  • google-maps-react 😂
  • @google-maps/react-wrapper
  • simple-react-google-maps [Sure, Jan]
  • react-maps-google [Now I'm just annoyed]
  • react-hook-google-maps [For those of you addicted to custom hooks for everything]
  • react-google-maps-loader 
  • react-static-google-map 
  • google-maps-react-17 [I guess the 17 is for React v17? Great, that will never go out of date]
  • google-maps-js-api-react

There are more, of course.  I feel like I'm in NYC looking for real Original Ray's.  Or maybe touring a graveyard.

So!  This is frustrating for a number of reasons:

  • They all solve the problem slightly differently, so the resulting React code can look vastly different depending on which one you use.
  • Looking for help on Stack Overflow or Google is difficult, because I keep winding up on help for a different repository.
  • The varying degrees of unmaintainedness [new word copyright me] of these repositories by their owners makes it hard to pick one; and I don't have a whole lot of faith that the one I pick will be maintained long-term.
  • My ultimate solution doesn't feel very React-like.  A lot of these packages tackle the simple case of adding a map element and some markers, but I wanted to go a little further than that by clustering close-together markers and adding a search bar.  I would expect to be able to add child elements to a parent map element that do that, but could not find a package that gives me that option.  I think I have a solution that works, but it involves creating a React useRef hook to manipulate the map object directly; not very React-y, definitely feels like I'm breaking some rules.
  • I'm sure there's a React developer out there who will say, "Oh of course you should use react-maps-google, you fool!  It's obviously the best one!"
I like React for simple things, and it's been good for quickly building up my frontend, but often when I get into more complicated scenarios, finding the correct path forward is non-obvious to say the least.  And this is a framework that came out nearly 10 years ago!  There have been so many fundamental changes to React that it's hard to keep up with the latest best practices, and among the community there seems to be a lot of disagreement on that anyway.  This situation with the dozen-plus possible Google Maps packages feels like more of the same chaotic soup.

Wednesday, September 21, 2022

Version 1.2.0 is live

 A few minor improvements:

  • Added a Mapbox search widget (called a Geocoder in code), which allows you to search and zoom the map to a destination.  Useful to search for sporting events near a specific landmark, hotel, address, etc.
  • Changed some data query profiles around so that events coming up in the upcoming week and upcoming month get refreshed more frequently.  (As always, check with official league and/or team online resources to verify up-to-date event venues, dates and times.)
What I'm working on next:
  • There are a couple of things Mapbox doesn't lend itself well to, especially for the mobile experience; I'd like to be able to group map pins together, for example.  Also I'm finding some locations aren't up to date in the search box (Seattle's Lumen Field is still called CenturyLink Field, for example).  I'll be experimenting with Google Maps' API to see if I like the user experience better (and also if I like the React developer experience any more or less!).
  • Some other UI elements need to be improved for the smartphone user experience, which is the dominant one these days.
  • The filter widget could use some alternate method to easily pick dates, like a calendar widget.  Will be looking around for one of those.
  • Filtering by sport would be nice.
Another future backlog item:
  • My data source has info on a lot more events that don't have venue location information attached.  I'd like to come up with a way to show a pin for the assumed venue based on the home team; this is going to take a little work to make sure I get it right.  If I can get it work, I can greatly increase the number of leagues and teams I show (for example, Japanese professional baseball, minor league baseball in the US, WNBA, etc.).  Ultimately I'd like to even show lower-league soccer; sometimes there's a team playing in your neighborhood and you wouldn't otherwise know it!  That could be a fun way to spur local community interest in more minor leagues and teams.  (Or, help you figure out something fun to do outside of the house when you're visiting relatives over the holidays...?)
Enjoy and beinvenue au monde sportif, bon voyage!

The perils of React

This was a great article on React that popped up in my Reddit feed:

I have my own feelings on React and the generally complex state of front-end web development today.  

I've worked on a lot of front-end code since 2013; we started bringing in React around 2015 and I immediately found it just really confusing. I've got a little better handle on it now, just built my own website (sportsmap.world!) with modern(-ish?) React and Typescript, which seems like generally a good combo for medium-complexity sites. I do like how the code looks with functional components and hooks, and I was able to find a library that wraps my map provider's components with React objects; it generally works pretty well.

But I agree with a lot of the points in the article, especially:

- Having to know the "Rules of Hooks" is bad; the rules should be more intuitive, or easier to spot or have called out at development time

- Having to read a dissertation on a hook to use it "properly" is bad

- Everybody's opinion of "properly" seems to be different

- The framework is bad at letting me know I'm doing it wrong

- Having to list out dependencies should be unnecessary

- Debugging rendering performance issues is painful, the solutions are usually non-obvious

- Outdated documentation, outdated code bases and packages, outdated Stack Overflow answers are all a huge problem.

And then just generally the whole thing about state management. This is a framework that updates my components based on changing state, but it just does not natively handle state well, for any site that's more complex than a few components. The fact we need to bring in some external package like a Redux to attempt to handle it feels like a massive shortfall.

I was indeed handling this stuff just fine on my own back in the day with MVVM organization and jQuery, and navigating these hurdles often doesn't make React feel like an improvement.

And then yeah, there's the fact that it's a Facebook joint; what if Facebook one day just decides they're going to up and charge to use the license? Doesn't feel far-fetched in 2022 when Meta is seeming to struggle to maintain its relevance.

Wednesday, September 14, 2022

Deciding on a web server

As a long-time software engineer, I've been party to more debates than I care to on the topic of which framework and/or language is the best one to use in a particular situation.

Real talk: Usually there's more than one perfectly fine option that will get the job done, which is the most important thing.  Ultimately the direction you go tends to wind up being matter of personal preference.  If you're starting a company or growing a team you might consider the type of engineer you want to hire on to help, and what kinds of technologies/languages would be best suited for that.  But, for this project, I expect it will just be me for now, so I wanted to pick technologies that would work best for me and get the job done.

One of my first technical decisions in building sportsmap.world was deciding what to use for a web server framework.  I knew I wanted one that could run a regular data collection job to query my sports schedule data source, store the query results in a local database instance, offer those results via an internal query endpoint, and serve it all up via web front-end endpoint.  I investigated a few possible choices, including Tomcat/Apache (which I was familiar with from working on Tableau Server), Jetty server, Node.js, Nginx, and Open Liberty.

Apache could definitely do everything I wanted, and familiarity with it was a plus.


  • Can code in Java, which is a more mature language with well-supported official frameworks and libraries.  
  • Works great with IntelliJ, my favorite IDE.  
  • Testing with JUnit feels like a snap and is also well-supported in IntelliJ.  
  • Attaching a debugger to root out problems is a lot easier.


  • Java is seen as antiquated in some circles, which isn't entirely fair.  I feel like it can get any job done pretty well, although it can feel like there's too much boilerplate code for simple things; some of the more modern Java features help alleviate this.  Still, it might not be the first choice for a startup-type environment, which is more what I'm going for.  
  • Spring tries to be one framework to rule them all, and I like it in some contexts, but I also find its paradigms around dependency injection to be pretty confusing and hard to configure correctly.  

Node.js, meanwhile, is a lighter weight option that I've mostly only used in testing and doing quick one-off projects.


  • Quick to spin up.  
  • It is a well-supported framework at this point.
  • The Express library makes it easy to add endpoints.  
  • There are a ton of open-source options to add functionality.


  • Server code written in JavaScript?  On my computer?  Extending the hastily conceived JavaScript beyond the world of browser front-ends feels like a mistake (although Typescript does address most of my concerns).  
  • Debugging is a chore and not well-supported.  IDE debugging is technically possible but difficult to set up -- I haven't even done it yet -- so I tend to rely on console logging, which feels like several steps backward.  
  • Visual Studio Code is not bad, but still doesn't feel as solid as IntelliJ.  
  • Although there are a lot of open source libraries, many of them tend to fall out of date or become unsupported over time, so managing dependencies could be challenging in the future.
Ultimately I chose Node.js for its light weight, and it's actually been a more solid environment than I expected.  So far I actually prefer the Node.js developer experience over React, which is surprising given the original purpose of JavaScript.

My early set-up steps were fairly simple:

Fairly quickly, I was able to build and run, and get a "Hello world" response from a listening port.  Ultimately, my backend runtime dependency list wound up looking like this:
  • Axios for making external API requests via HTTP
  • axios-rate-limit to avoid flooding external API endpoints
  • cors for allowing internal requests to server endpoints
  • dotenv for enabling .env configuration files, good for storing local development settings and API keys
  • Express
  • luxon for handling time-based calculations and time zones more gracefully than native JavaScript (a replacement for moment,js, no longer supported)
  • node-pg-migrate, for postgres schema migrations
  • pg, for postgres operations
Using those libraries, I have a server that makes external API calls on a set schedule, stores the query results in postgres, and provides endpoints the front end can call.  Additional libraries allow for testing and verifying operations against postgres.  It all manages to feel quick and lightweight but also robust and reliable enough for what I wanted to accomplish.  So overall, I've been satisfied and pleasantly surprised with Node.js.

Tips for sports tourism planning and travel

Welcome to the sportsmap.world blog!  Here I'll be posting about sports tourism, as well as some of the challenges I faced building up the sportsmap.world main site.

First, some tips for planning and travel:

  • Always verify event times and locations, which can change.  For smaller leagues, search for the home team's website or contact their ticket office, if applicable.
  • Acquiring tickets can be more difficult than you might expect, depending on the country, sport, and league.  Most North American-based teams sell individual tickets via their website or a ticket seller like Ticketmaster, and seating is generally unrestricted; conversely, some European soccer teams may only sell tickets to their supporters club members, and supporters of the visiting team are seated separately.  I've had the most success dealing directly with the home team's ticketing website.  If you're not sure about the best way to acquire tickets, check with the home team's website or ticket office to verify details.
  • Beware of third-party tickets resellers; watch out for scams, overpriced tickets, or deals that look too good to be true.
  • Many sports tickets these days are distributed digitally; if that's the case for your event, make sure you're familiar with the digital ticketing system being used, and ensure that you can log in to retrieve your tickets ahead of time.  It's a good idea to download digital tickets to your phone's wallet app, if available, for quick retrieval at the entry gate; or, print tickets with barcodes before leaving home.
  • Be aware that different events can have widely disparate atmospheres.  Some European soccer matches or American football matches might have rowdy and aggressive fans, and wouldn't be as suitable for families with small children or those who are looking for a more chill experience.  If that's the case for you, consider checking out a smaller stadium, a lower-level league, or a sports that's not as popular with the locals.  These smaller events can be just as fun!
  • When visiting a foreign country, always be a good guest; when visiting a foreign stadium, be a good fan!  Use public transportation when available; take in the atmosphere; get to know the locals; drink the local beers; and most of all, don't be a jerk.  
Have fun planning, and bon voyage!