Enhancing Apollo Cache Updates using TypeScript null checks

Currently, I am utilizing apollo codgen to automatically generate types for my graphql queries in TypeScript. However, I have noticed that the generated types contain numerous instances of null values, leading to an abundance of if checks throughout my code. Is this typical practice when working with graphql cache updates in TypeScript?

this.props.mutate({
  variables,
  update: (proxy, { data }) => {
    // Having to handle null values at every step
    if (!data || !data.createContact || !data.createContact.contact) return;
    let newContactEdge = {
      node: { ...data.createContact.contact, __typename: 'Contact' },
      __typename: 'ContactEdge',
    };

    // Reading from cache
    let listCache = proxy.readQuery<ListContactsQuery>({ query: ChatAPI.queries.listContacts });

    // Dealing with more null values
    if (listCache && listCache.contacts && listCache.contacts.edges) {
      proxy.writeQuery({
        query: ChatAPI.queries.listContacts,
        data: {
          ...listCache,
          contacts: {
            ...listCache.contacts,
            edges: [newContactEdge, ...listCache.contacts.edges],
          },
        },
      });
    }
  },
})

This approach feels cumbersome as previously, checking if cache was not null ensured that the data would be accessible without descending into nested null checks.

Below are the generated types for the ListContactsQuery:

export interface ListContactsQuery_contacts_edges {
    __typename: "ContactEdge";
    /**
     * The item at the end of the edge.
     */
    node: ListContactsQuery_contacts_edges_node | null;
}
export interface ListContactsQuery_contacts {
    __typename: "ContactConnection";
    /**
     * A list of edges.
     */
    edges: (ListContactsQuery_contacts_edges | null)[] | null;
}
export interface ListContactsQuery {
    /**
     * Retrieves all contacts for the current user
     */
    contacts: ListContactsQuery_contacts;
}

Answer №1

Although it may be a bit late, there is still potential value in this information. To minimize the need for null checks (or excessive Maybe<> types) on the client-side, you must properly configure your server-side schema. For example, in GraphQL .net:

    Field<ListGraphType<RoleType>>()
            .Name(QueryName.Roles)
            .Resolve(context => AuthRoleRepo.LoadAllAuthRoles())
            .RequirePermission(Const.Roles.Admin);

can be transformed into

    Field<NonNullGraphType<ListGraphType<NonNullGraphType<RoleType>>>>()
            .Name(QueryName.Roles)
            .Resolve(context => AuthRoleRepo.LoadAllAuthRoles())
            .RequirePermission(Const.Roles.Admin);

Take note of all the NonNullGraphType specifications for the return type. ListGraphType<RoleType> =>

NonNullGraphType<ListGraphType<NonNullGraphType<RoleType>>>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When the file is active on a local machine, the bot commands run smoothly. However, these commands do not execute on a remote

Lately, while working on coding a discord bot using discord.js, I came across an issue. Whenever I run my bot on my local machine, all the commands work perfectly fine. However, after committing and pushing the code to GitHub, and then allowing buddy.works ...

Error: Trying to access a property that does not exist on an undefined object (retrieving 'kind

Currently, I am working on a project using angular-CLI. When I attempted to create a new module yesterday, an error popped up in the terminal saying Cannot read properties of undefined (reading 'kind') (only this error there wasn't an ...

Implement a delay for a specific function and try again if the delay expires

In my TypeScript code, I am utilizing two fetch calls - one to retrieve an access token and the other to make the actual API call. I am looking to implement a 1-second timeout for the second API call. In the event of a timeout, a retry should be attempted ...

Learn the steps to refresh a component in Angular 5

src/shared.service.ts public _testData:any;   set testData(value:any) {     this._testData = value   }   get testData():any {     return this._testData;   } src/header.component.ts private postValues( ...

The positioning of Material UI InputAdornment icons is located beyond the boundaries of the TextField input area

I am struggling to understand why my InputAdornment is not positioned correctly. There doesn't seem to be any style in my code that would affect the location of the icon within the TextField (such as padding or flex properties). Currently, the calen ...

Unit test: Using subjects instead of observables to mock a service and test the change of values over time results in TypeScript throwing error TS2339

I have a unique scenario where I have implemented a service that accesses ngrx selectors and a component that utilizes this service by injecting it and adjusting properties based on the values retrieved. For unit testing purposes, I am creating mock versi ...

Asynchronous waiting waits not for async await

I'm currently working on a function that loops through an array and updates the model for each ID, then adds the result to another array. This is the code snippet I have: async function getSortedAnimals() { var i = 0; var sortedAnimals = []; id ...

Error encountered when attempting to locate the file declaration for module 'jwt-decode'

Currently, I am utilizing the Visual Studio 2017 template for my Angular project and encountering an issue when attempting to import the 'jwt-decode' module after adding it to package.json. The error (mentioned in the title of my post) arises aft ...

Encountering the error "No overload matches this call" while utilizing useQuery in TypeScript may indicate a mismatch in function parameters

My issue lies with TypeScript and types. Here is the API I am working with: export const clientAPI ={ //... getOptions: async (myParam: number) => get<{ options: Options[]; courses: any[] }>(`/courses?myParam=${myParam}`)().then((result) =& ...

Can JSON Web Tokens be utilized in a browser environment?

Searching for a way to parse the JWT token led me to this jsonwebtoken library https://www.npmjs.com/package/jsonwebtoken. It appears to be tailored for NodeJS. Is it feasible to utilize this library in the browser? My attempts so far have resulted in the ...

Implementing try-catch logic for element visibility in Playwright using TypeScript poses limitations

There is a specific scenario I need to automate where if the title of a page is "Sample title", then I must mark the test as successful. Otherwise, if that condition is not met, I have to interact with another element on the page and verify if the title ch ...

Encountering Compilation Issues Post Upgrading to Angular 9

I recently upgraded my Angular application from version 8 to version 9, following the official guide. However, after the upgrade, I encountered errors that prevent my application from building. The specific errors include: "Module not found: Error: Can ...

Toggling multiple ions simultaneously does not function independently

I encountered a problem while working on an ionic app. I needed to have individual control over toggle switches, but my current code toggles all switches at once whenever one switch is tapped. Is there a way to fix this and manage each toggle switch separa ...

There are no properties shared between type 'dateStyle: string' and type 'DateTimeFormatOptions'

"typescript": "^4.0.3" Can anyone help me resolve the TypeScript error I am encountering in the code below?: components/OrderListItem.tsx const newedate = (_date) => { const options = {dateStyle: 'medium'}; //{ weekday: ...

Adding a QR code on top of an image in a PDF using TypeScript

Incorporating TypeScript and PdfMakeWrapper library, I am creating PDFs on a website integrated with svg images and QR codes. Below is a snippet of the code in question: async generatePDF(ID_PRODUCT: string) { PdfMakeWrapper.setFonts(pdfFonts); ...

Issue with Jest mock function failing to trigger axios instance function causing it to return undefined

I initially found a solution on this StackOverflow thread However, I wanted to add my own helper function that generates a fresh Axios instance with the user's authentication token. Here is what I came up with: import axios from "axios"; c ...

Creating an NPM package that utilizes global types without altering the project it is integrated with

The Dilemma: When working on a project that involves reusing multiple types across various files, utilizing types defined in a script file can be advantageous. These global types are accessible throughout the entire project without the need for importing, ...

When converting a PDF to a PNG, the precious data often disappears in the process

I am currently facing a problem with the conversion of PDF to PNG images for my application. I am utilizing the pdfjs-dist library and NodeCanvasFactory functionality, but encountering data loss post-conversion. class NodeCanvasFactory { create(w, h) { ...

What could be causing the countdown timer to speed up unexpectedly?

Currently, I am developing a quiz application. At the moment, I need to implement the following features: Countdown timer Questions Question Choices The countdown timer for each question functions properly as long as the answer button is not clicked or ...

Upgrading my loop React component from vanilla JavaScript to TypeScript for improved efficiency and functionality

After seeking assistance from Stack Overflow, I successfully created a loop in React using a functional component that works as intended. However, I am encountering errors while trying to refactor the loop to TypeScript. The code for my DetailedProduct c ...