Building my own iPhone Availability Web App

Before I begin, a quick disclaimer. What I’m building here is completely for fun and because I thought it might be interesting. I’m critiquing and improving a form that was built by people smarter than me and more than adequate for 99.99% of users. Basically, I saw something I wanted to build and I did it.

I’m currently the owner of an HTC M8 phone - my foray back into Android after using an iPhone for a couple of versions. I like the HTC UI, and in general, the phone was pretty incredible, but after the most recent Android OS update, my phone began to get more and more sluggish. It got to a point where just opening up the phone to take a picture would take 30-60 seconds for it to respond. Phone calls, which I don’t get many of, were even worse. When I missed a call because my phone’s basic UI wouldn’t respond I nearly threw the thing in the pool. I tried many things but eventually wiped the phone and restored from a back up. It “helped”, but the phone is still chunky. I decided it was time to switch back to iOS and I figured the iPhone 6S+ would be a great phone to pick up. I also decided that the new iPhone upgrade program would be a good fit. From what I’ve read it is better than ATT’s Next program. The only problem is that you must go to an Apple store to sign up for the program. My nearest Apple store is in Baton Rouge, about an hour away. Worth a drive, but only if I know I’ll have a device there to pick up.

Luckily, Apple has a cool form you can use to see if your desired phone is available. You select your state, your store, your model, and then your carrier:

As you can see, none are available. (Sigh.) You can switch to SIM-free of course (and I checked, my HTC and the 6S+ use the same type of SIM). What bothered me about this form were a couple of issues.

First off - you can't use it before 8AM. No, wait, stop laughing, I'm serious. It's a web based system with "open" hours like a retail store. There's probably a data reason for that. I spoke with an Apple rep last week and they mentioned they get new inventory data at 8. I'd like to imagine that Apple stores have some sophisticated real time hook into inventory but that's probably not the case. Still, it is kind of shocking to see a "closed" sign at a web site.

When I was in CA last week, I tried to search around me. Every time you switch stores, the form rebuilds. So if I've selected 6S+ and ATT, I lose those selections. Now, the reason for this makes sense. It is possible that the other store doesn't have 6S+ or ATT available, but it still annoying. That's the kind of problem that intelligent front-end code could handle gracefully. There were 5-6 stores around me in South San Francisco and I checked every day there and those damn drop downs annoyed me every day. (As I said on top though, I'm probably not the target user here.)

Finally, it would have been really nice if I could have simply said, "Tell me when a 6S+ for ATT or SIM-free is available in gray or silver that has 64 GB since 16 is just plain stupid." But apparently Apple isn't having any difficulty selling iPhones so such a system probably isn't a high priority for them. (And to be clear, this is just for the upgrade program. Obviously the 'regular' store lets you buy right now.)
</ul>
So - bored this weekend - I did what any self-respecting web dev does - I opened up dev tools while using the form. First thing I noticed was that the app was hitting JSON files to drive the drop downs:
I then opened each of those files and took a look at the JSON. stores.json was a literal listing of all the stores with availability. Here is a snippet:

The key there is the store and each line item (except for timeSlot) represents a model/color/carrier/size line item. So given that I could get the data (right click in dev tools and open them in a new tab, then save as), I began work on a web app that would let me parse the data my own way. Specifically I wanted a few things:

Let me specify a store, and then multiple stores.

Let me specify any model I want.

Let me specify multiple carriers.

I also wanted to ignore 16GB, but at the end decided against that. I began working on my own code that would suck in the JSON files (my local copy) and let me parse it myself. I'll show the result first and then talk about the code. And yes - mine is far less pretty than Apple's.
On top you can see a state drop down and store selector. As I said, my initial plan was to provide for adding multiple stores, but I never got around to that.
Below it you can see the carrier and model selections. Below it is the grid of options. I used CSS (woot) to gray/blur options that weren't available. How did I get the Apple iPhone colors? Did you know Firefox has a color picker builtin to their dev tools?
The circles on the Apple store actually have nice gradients as you move from the center of the circle to the outside. I just clicked "in the middle-ish" to get a value that looked good to me.
Ok, so let's now get into the code. I began with a simple setup routine:

I'll skip doStoresForStates, that simply gives me a root variable keyed by state that includes an array of stores. doStateDropDowns populates the state drop down. As I mentioned, the idea was to make it so you could add multiple stores, but I never got to that.

Ok, so now came the scary part - building the actual "based on what you select, filter results" stuff. The first issue I ran into was model data. As I said, every model/capacity/color/carrier had a unique ID. I could have typed this all by hand, but instead, I used dev tools:

What you are seeing is code I ran in the browser console. It fetched each "cell" of the display, got the value (which was the product id), and then used copy to put it in my clipboard. I could then paste into my code. There are 5 carriers and 2 models, so I had to do this 10 times, but it took all of 1 or 2 minutes so it wasn't a big deal.
The filtering code is a big hot mess. Like, seriously. It seems to work, but I put no warranty on it. Here it is - don't laugh too hard at me.

Basically - I loop over a capacity and color array and then check the availability at each location. (Again, remember I was going to support multiple locations.) getModels is a utility function that parses the model data I gleaned from dev tools. I then simply add in/remove a CSS class to add the nice gray/blur affect.
That was the front end. In order to keep the application up to date I wrapped the whole thing up in a Node.js app running on IBM Bluemix. All I needed was the ability to suck down the JSON files from Apple on a scheduled basis, and for that I used a cron library I used over at ColdFusion Bloggers. Here is the entirety of the app:

I don't have any error handling on the sync function so it is brittle as heck, but it gets the job down. I also set it up to hit Apple once ever 2 hours. I figured that was gentle and wouldn't over tax Apple.com. I also built in a route I could use for manual testing, but I removed that when I deployed it up to Bluemix.
You can see it yourself here: http://applestorechecker.mybluemix.net/. As I said, it is somewhat brittle. I could also add a simple 'data files last updated at X' to the header so you know how fresh the data is. If I weren't being lazy, I could also add the ability for you to register when your desired model/color/carrier/store has product available, but, alas, I'm lazy today.
Any way, check it out, and let me know if you have any questions!

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos.
If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.