The Problem

There are times when you want to fetch data from your server that is occasionally changed. For example, getting the number of unread messages in an application. There are a few possible solutions for keeping the data up-to-date with the backend. 1) You can poll the server every X minutes, or 2) you can use “cache-and-network” to utilize the cache first, but also check the server for updated data.

Polling

If you choose to poll for new messages, you run the risk of your application constantly calling the server for data even though the user has not recently interacted with the page. Think, checking another tab or walking away from the computer for a while. While not detrimental, this results in a lot of wasted calls and network requests.

Cache and Network

This method ensures you always have the most up-to-date information from the server, but also results in a lot of needless calls to the server. The client is constantly saying, “Ok, I’ll use the cache, but let me still call the server to check for updated data.” This query/hook may run multiple times on a single user interaction and is still to aggressive for data that only updates every few minutes.

The Solution

What we really want is the best of both worlds. We want to utilize the cache as much as possible, but also set an expiration for when to grab fresh data from the server. We can use a simple technique of utilizing Map and dates to accomplish this goal.

We’ll simply make a unique “key” for our query and record the last time we fetched that key. When we call useQuery, we pass it our “key” and the expected expiration time. If the “key” is still valid, we return to useQuery the fetchPolicy of “cache-first.” This means, use the cache if it exists and otherwise fetch from the server. If the “key” is invalid, we call useQuery with “network-only” which calls the server to refresh the data. And at the same time, we update the last fetched time of the key.

Let’s take a look at an example of the getFetchPolicyForKey() function and its implementation.

useUnreadMessages.ts

And here’s the implementation of the cache check and when to return each fetch policy.

getFetchPolicyForKey.ts

I’d like to share the spreadsheet I use for tracking my entire financial overview. I’ve always preferred keeping track of my accounts in a spreadsheet for 2 reasons. (1) I don’t like giving my personal financial information to a 3rd party. (2) I can use spreadsheets to analyze data and even perform custom calculations. Such as, what’s the delta on the current price vs the 52 week low.

I’ve been slowly building this over the last few years and it is finally time to share V2. Here are the main features I like about this spreadsheet:

  • Tracks investments across multiple institutions and account types (IRA, 401k, brokerage)
  • Shows portfolio distribution by holding type and account
  • Tracks heaviest investments across all accounts
  • Live charts for stocks
  • Live expense ratios for ETFs and Funds
  • Track heaviest positions across stocks and funds
  • See your diversification across accounts and investment categories

So without further ado, here is the spreadsheet for you to copy.

See types of diversification
Track heaviest positions

We’ve been having bad air in the Bay Area for a few weeks now and it got me wondering how much was seeping into my house and garage. After a little tinkering, I finished a custom, portable PM2.5 and PM10.0 sensor. The initial build used a SDS011, which promptly died after a week. I moved on to the “less” accurate PMS5003 and have been quite happy with the results. Here’s the sensor in action.

I’d like to share the spreadsheet I use for tracking my portfolio. I’ve always preferred keeping track of my portfolio in a spreadsheet for 2 reasons. (1) I don’t like giving my personal financial information to a 3rd party. (2) I can use spreadsheets to analyze data and even perform custom calculations. Such as, what’s the delta on the current price vs the 52 week low.

I’ve been slowly building this over the last few years and it is finally time to share. Here are the main features I like about this spreadsheet:

  • Tracks investments across multiple institutions and account types (IRA, 401k, brokerage)
  • Shows portfolio distribution by holding type and account
  • Tracks heaviest investments across all accounts
  • Live charts for stocks
  • Live expense ratios for ETFs and Funds

So without further ado, here is the spreadsheet for you to copy.

Six months ago I was looking for a new MTG group in my area. After a post on Nextdoor went up, I replied with my interest. There was a little chatter in the thread, but nothing really came of it.

Fast forward 6 months, I receive a direct message asking me if I could help evaluate some Magic cards.

So, I run a site called SellMyMTG.com and get these kinds of emails all the time. People have Magic cards from when they were kids or a relative passed away, and they just need some guidance on what to do with them. I help provide fair prices for the cards and about half the time also end up buying some cards.

Occasionally people tell me they have super rare cards, but when meeting in person, these cards are either fakes or the wrong edition. (Too new and not considered highly valuable) So naturally, I was skeptical about the claims from the above person. A Black Lotus is considered to be one of the most rare and valuable cards in all of magic. In fact, one had just sold on Ebay for $166,000. So having two of them and a beta starter deck box is just unheard of.

So Al texted me and told me the cards are not actually his. Ah, a flaw in the story already and leading to less credibility of the cards actually being real. But then he sent me the following picture.

This is an unopened box of Beta Starter Decks from the second print run of Magic in 1993. These are so rare it’s hard to even find a picture of them on the internet. In fact, in this condition and unopened, there are maybe 10 in the world. They are extremely rare.

At this point, I was super skeptical, but damn curious to see if it could possibly be true. I agreed to meetup in person to see the collection and help evaluate the cards. We picked a location nearby and Al introduced me to his friend, Gary. Gary pulled the following out of a Trader Joe’s bag.

Unopened boxes of Beta, Unlimited, Arabian Nights, Legends, Antiquities and The Dark
2 Black Lotus and tons of other rare Beta cards from 1993

I was absolutely flabbergasted. I stumble for words. “How is this possible?” Gary replies, “Oh, these are my dad’s. Steve Wozniak.” Ummmmm, yeah, well that would make perfect sense.

Partial Unlimited Set

We pulled out the cards and in addition to the unopened boxes, there was a full set of Beta and almost full set of Unlimited. All in beautiful condition, absolutely real and untouched for 24 years.

Arabian Nights Booster Box

I started off by helping them understand just how rare these cards and boxes are. We went over the prices for the items to get an overall idea of what we’re working with and it was substantial. I helped them sort through boxes of cards to find the most valuable ones and made piles of cards that should be graded.

As we wrapped up and the elation of holding these astounding pieces of history wore off, Gary mentioned he wanted to get some value right away. I went over options for selling individual cards (eBay, card store, buylisting, auction house), but I also offered to buy some of the cards in person. I encouraged him to keep the Beta set together, so he agreed to sell the unlimited cards.

In my early days of collecting, I had been personally scammed by someone who knew more than me. I was over-eager and not careful enough. And as these things go, ultimately I got burned. It’s an awful feeling and something I would never wish on anyone. So to ensure fairness, I encouraged us to lookup the prices of each card using Ebay Sold listings as well as a few buylists. After quite some time, we mutually came to a deal and I got that much closer to my Unlimited Set.

Then the question of the boxes remained. Although I was tempted to buy some, they were just simply out of my price range. In addition, I felt such rare pieces deserved a bigger audience to help ensure the right price was paid.

Beta Starter Deck Box

I followed up by texting Gary the emails of the “high rollers” in the the Magic community. Once again there was a lot of skepticism on the part of these buyers. This kind of thing doesn’t happen every day. But within 24 hours, a deal was made to purchase all the boxes in a face-to-face exchange with Steve Wozniak. And by generous offer of Gary, he invited me to join the exchange.

A few weeks later, the day had come. I headed downtown to see the exchange with Steve and the buyers. I had no idea what to expect, but brought a few decks just in case.

As I arrived at the hotel, I saw Steve in the lobby and said a quick hello. He was delightfully warm, but reserved to start. When Gary arrived, we went up the elevator to the suite where the buyers and card graders awaited. The moment we walked through the door, Steve lit up and entranced the whole room. He began telling stories, cracking jokes and showing of his famous $2 bills. As we settled in, Steve signed the boxes being sold, as well as a few playmats.

He regaled us with the story of where the boxes had come from (a little card shop in Los Gatos) and how he purchased them to make his decks better. To cap off the afternoon, the buyers offered Steve a Beta starter pack to open. We watched carefully as he revealed each card, culminating in the final rare.

We spent the rest of the afternoon playing Magic, talking about the “old days” and taking a few photos. In short, it was nothing short of a magical afternoon.

Steve, Tony, Gary

Let’s say you’re sending a button from a parent to a child using render props.  How do you properly render and place the returned button?

As it turns out, its quite easy.

Let’s say that this is your component which uses render props to return both the toggle state and the toggle button.

To use the above provider, you may be tempted (because of patterns) to do this.

However, because the parent has already rendered the button, the child needs only to place the rendered component as if it were any other variable.

That’s it.