<?xml version="1.0" ?>
<rss
  version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom"
>
  <channel>
    <title>Blog - Ryan Elainska</title>
    <link>https://www.ryanelainska.com/blog</link>
    <description>Ryan Elainska - Tutorials</description>
    <language>en</language>
    <atom:link href="https://www.ryanelainska.com/rss-dev.xml" rel="self" type="application/rss+xml"/>
    
      <item>
        <guid>https://www.ryanelainska.com/blog/apollo-getcachekey-with-typescript</guid>
        <title>Apollo getCacheKey() with TypeScript</title>
        <link>https://www.ryanelainska.com/blog/apollo-getcachekey-with-typescript</link>
        <description>A guick guide to using the Apollo client's getCacheKey() method with TypeScript</description>
        <content:encoded><![CDATA[<article class="w-full max-w-full "><h1>Apollo getCacheKey() with TypeScript</h1><p>I’m currently working on the front end of an app that uses React + Apollo (via <code>apollo-boost</code>) + TypeScript. I’m to the point where I’m retrieving items from the cache in my resolvers using fragments<sup id="fnref-1"><a href="#fn-1" target="_self" rel="noopener noreferrer" class="footnote-ref">1</a></sup>, which means I need to use <code>getCacheKey()</code> to search for the item’s cache key using its ID field. (In this app, it would probably work to just assume the cache key is <em>TypeName:UUID</em>, but you never know, so we should probably do things properly.)</p><p>Unfortunately, I have not been able to find the correct typings for <code>getCacheKey()</code>. When passing in <code>cache</code> as an argument to a resolver, one can import <code>NormalizedCacheObject</code> for the typings, like so:</p><pre><code class="language-tsx">import { ApolloCache } from &#x27;apollo-cache&#x27;
import { NormalizedCacheObject } from &#x27;apollo-boost&#x27;

...

Mutation: {
  resolveSomeStuff: (
    _: undefined,
    { itemId, itemOptions }: { itemId: string; itemOptions: Array&lt;string&gt; },
    { cache }: { cache: ApolloCache&lt;NormalizedCacheObject&gt; }
  ) =&gt; {
  /* Now we resolve everything. Global warming, world
  hunger, over- and under-population.... */
  ...
  }
}
</code></pre><p>Inside my resolver, the Apollo docs tell me to get an item’s cacheKey like this:</p><pre><code class="language-tsx">const cacheKey = cache.getCacheKey({ __typename: &quot;Item&quot;, id: itemId })
</code></pre><p>Unfortunately, if I use this formulation, tslint will yell at me:</p><p><strong>“Property ‘getCacheKey’ does not exist on type ‘ApolloCache’.”</strong></p><p>Well.</p><p>Half an hour of Googling was unhelpful. But eventually I found someone reporting a similar-sounding problem as an issue over at the <a href="https://github.com/apollographql/apollo-client-devtools/issues/136" title="GitHub issue with apollo-devtools" target="_blank" rel="noopener noreferrer" class="">apollo devtools repo</a>. I adopted his workaround, and it was effective for me. So here is the code inside my resolver:</p><pre><code class="language-tsx">const cacheKey = cache[&quot;config&quot;].dataIdFromObject({
  __typename: &quot;Item&quot;,
  id: itemId,
})
</code></pre><p>This essentially does an end run around the problem by not calling <code>getCacheKey()</code> at all. I don’t know enough about the inner workings of the Apollo client to understand why this works, but I kind of don’t care.</p><div class="footnotes"><hr/><ol><li id="fn-1">If you don’t know what some or all of that means, this post probably isn’t for you.<a href="#fnref-1" target="_self" rel="noopener noreferrer" class="footnote-backref"><code>↩</code></a></li></ol></div></article>]]></content:encoded>
        <pubDate>Mon, 17 Jun 2019 00:00:00 GMT</pubDate>
      </item>
  
      <item>
        <guid>https://www.ryanelainska.com/blog/async-datafetching-sandbox</guid>
        <title>Async Data-Fetching Sandbox</title>
        <link>https://www.ryanelainska.com/blog/async-datafetching-sandbox</link>
        <description><![CDATA[<article class="w-full max-w-full "><h1>Async Data-Fetching Sandbox</h1><p>I recently needed to mock a very basic generic asynchronous data-fetching API with loading state in order to create a GitHub issue. I have a feeling it’ll be useful later, possibly even to other people, so here it is:</p><p><a href="https://codesandbox.io/s/async-data-update-starter-xf3oq" target="_blank" rel="noopener noreferrer" class="">https://codesandbox.io/s/async-data-update-starter-xf3oq</a></p><p>It uses a promisified wrapper around <code>localStorage</code>, with timeouts to simulate the async data-fetching, and local React state for <code>loading</code>, because my original use case for it was simulating a common pattern with the Apollo client. (But this should work for other kinds of async data-fetching.) It doesn’t really do much out of the box other than render a stringified version of the original data; even the data-update handler is commented out. Wire up however makes sense for you.</p></article>]]></description>
        
        <pubDate>Wed, 02 Jun 2021 00:00:00 GMT</pubDate>
      </item>
  
      <item>
        <guid>https://www.ryanelainska.com/blog/build-a-modern-graphql-api-with-prisma</guid>
        <title>Build a Modern GraphQL API with Prisma</title>
        <link>https://www.ryanelainska.com/blog/build-a-modern-graphql-api-with-prisma</link>
        <description>Learn to use Prisma, a powerful, type-safe ORM to build a modern GraphQL API in this new course by Ryan at Level Up Tutorials</description>
        
        <pubDate>Tue, 16 Nov 2021 00:00:00 GMT</pubDate>
      </item>
  
      <item>
        <guid>https://www.ryanelainska.com/blog/gatsby-plugin-favicon</guid>
        <title>gatsby-plugin-favicon</title>
        <link>https://www.ryanelainska.com/blog/gatsby-plugin-favicon</link>
        <description>First I had to get past what seemed like a dealbreaker: Running gatsby develop with the plugin installed caused the terminal to hang.</description>
        
        <pubDate>Sat, 12 Jun 2021 00:00:00 GMT</pubDate>
      </item>
  
      <item>
        <guid>https://www.ryanelainska.com/blog/google-tag-manager-in-react</guid>
        <title>How to Set up Google Tag Manager in NextJS</title>
        <link>https://www.ryanelainska.com/blog/google-tag-manager-in-react</link>
        <description>Make your marketing team happy by configuring GTM to track your single page app performance</description>
        
        <pubDate>Sun, 01 Nov 2020 00:00:00 GMT</pubDate>
      </item>
  
      <item>
        <guid>https://www.ryanelainska.com/blog/how-to-patch-an-npm-package-with-yarn-patch</guid>
        <title>How to Patch an npm Package with `yarn patch`</title>
        <link>https://www.ryanelainska.com/blog/how-to-patch-an-npm-package-with-yarn-patch</link>
        <description>One of the new features of yarn 2.0 is the ability to modify an installed package in-place, so you can incorporate your own changes or bugfixes without having to wait for the package maintainer to make those changes—or, indeed, so you can make changes you think the maintainer will not make at all.</description>
        
        <pubDate>Wed, 02 Jun 2021 00:00:00 GMT</pubDate>
      </item>
  
      <item>
        <guid>https://www.ryanelainska.com/blog/nextjs-starter</guid>
        <title>Save 20 Minutes Every Time with this Complete NextJS Config</title>
        <link>https://www.ryanelainska.com/blog/nextjs-starter</link>
        <description>By the time you've finished this guide, you'll have a repo you can clone every time you start a new project. You can skip all that swearing and hair-pulling and get right down to coding.</description>
        
        <pubDate>Tue, 13 Jun 2023 00:00:00 GMT</pubDate>
      </item>
  
      <item>
        <guid>https://www.ryanelainska.com/blog/run-this-applescript-to-hear-your-music-in-glorious-mono</guid>
        <title>Run this AppleScript to Hear your Music in Glorious Mono</title>
        <link>https://www.ryanelainska.com/blog/run-this-applescript-to-hear-your-music-in-glorious-mono</link>
        <description>I often work while my son is sleeping or napping. My desk is right outside his room, so if I want to listen to music, I need to use headphones. But I'm also often the primary caregiver at the moment and need to keep one ear open so I can hear if he needs something, which means if I want to listen to music I need to use head*phone*.</description>
        
        <pubDate>Wed, 02 Jun 2021 00:00:00 GMT</pubDate>
      </item>
  
      <item>
        <guid>https://www.ryanelainska.com/blog/how-to-persist-react-form-state-to-url-search-params</guid>
        <title>How to Persist React Form State to URL Search Params</title>
        <link>https://www.ryanelainska.com/blog/how-to-persist-react-form-state-to-url-search-params</link>
        <description>Use URLSearchParams to persist your form state across sessions and make it shareable.</description>
        
        <pubDate>Wed, 24 Jan 2024 00:00:00 GMT</pubDate>
      </item>
  
  </channel>
</rss>
