Revisiting unions with TypeGraphQL

Here is the code snippet I'm working with:

const retrieveUsers = ({
  Model, options,
}) => Model.find(options).catch((e) => {
  throw e;
});

@ObjectType({ description: "User model" })
@Entity()
export class UserModel extends BaseEntity {
    ...
}

@ObjectType()
class Error {
  constructor(data: {message: string, code: number}) {
    this.message = data.message;
    this.code = data.code;
  }
  @Field(() => Int)
  code: number;
  @Field(() => String)
  message: string;
}

@ObjectType()
class Success {
  @Field(() => [ UserModel ])
  users: [UserModel];
}

const UserResponseType = createUnionType({
  name: "UserResponseType",
  types: () => [
    Success,
    Error,
  ] as const,
});

@Query(() => [ UserResponseType ])
async retrieveAllUsers(): Promise<typeof UserResponseType> {
  const errors = await Promise.resolve([
    new Error({
      code: 501,
      message: "test",
    }),
  ]);
  const users = await retrieveUsers({
    Model: UserModel,
    options: {
      ...
    },
  }).catch((e) => e);
  return {
    errors,
    success: users,
  };
}

I am aiming to be able to query for Errors or Success in a specific way like this:

query retrieveAllUsers {
  retrieveAllUsers {
    ... on Success {
      user {
        id
        email
      }
    }
    ... on Error {
      code
      message
    }
  }
}

However, I encountered an error stating:

TS2322: Type '{ errors: Error[]; success: any; }' is not assignable to type 'Error | Success'.
Object literal may only specify known properties, and 'errors' does not exist in type 'Error | Success'.

I attempted to follow an example from (https://typegraphql.com/docs/unions.html#docsNav)[this source]. How can I achieve the mentioned above ability to query?

Answer №1

The asynchronous function getAllUsers() is not returning a value that matches the specified return type

Promise<typeof UserResponseType>
, leading to the occurrence of the error TS2322.

Currently, the function returns an object containing properties for both errors and success, but it should ideally return either an instance of Error or Success. The revised implementation below demonstrates this:

import {
  createUnionType,
  Field,
  Int,
  ObjectType,
  Query,
  Resolver,
} from "type-graphql";

@ObjectType({ description: "User model" })
export class UserModel {
  @Field()
  id: string;
}

@ObjectType()
class Error {
  @Field(() => Int)
  code: number;
  @Field(() => String)
  message: string;
}

@ObjectType()
class Success {
  @Field(() => [UserModel])
  users: Array<UserModel>;
}

const UserResponseType = createUnionType({
  name: "UserResponseType",
  types: () => [Success, Error] as const,
  resolveType: (value) => {
    if ("code" in value) {
      return Error;
    }
    if ("users" in value) {
      return Success;
    }
    return undefined;
  },
});

@Resolver()
export class UserResolver {
  @Query(() => UserResponseType)
  async getAllUsers(): Promise<typeof UserResponseType> {
    const error: Error = {
      code: 501,
      message: "test",
    };
    const success: Success = { users: [{ id: "1" }, { id: "2" }] };
    return success;
  }
}

Executing the provided query will now fetch and display the user ids. By changing return success; to return error;, the query will instead display details related to the error.

query getAllUsers {
  getAllUsers {
    ... on Success {
      users {
        id
      }
    }
    ... on Error {
      code
      message
    }
  }
}

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

How can I retrieve the name of a React component in the most effective way?

My current challenge is figuring out how to retrieve the name of a React component. I initially attempted using the this.constructor.name property, but discovered that it doesn't function properly in production mode due to code minification by Webpack ...

Encountering challenges with implementing debouncing functionality in React programming

import React,{useState} from 'react'; const app = () => { const [inputValue, setInputValue] = useState(); const handleChange = (e) => { setInputValue(e.target.value); console.log(inputValue); } const d ...

What is the best way to generate hyperlinks from data in a MongoDB database?

Looking for some assistance in setting up an online discussion forum using node.js, express & mongodb. My current challenge is creating clickable links that will redirect me to the specific page of each article stored in the database. I need to figure out ...

JQuery/JS function not functioning as expected

Creating HTML with jQuery to retrieve data from a web API. At the start of my script, I defined a function that checks the selected value of a dropdown and assigns it to a global variable. var $seldom; $(document).ready(function () { function chkdom() ...

I am interested in obtaining every separate return value from the reduce() function instead of just the final total

initialValue currentValue position elements final value first calculation 0 1 1 [0, 1, 2, 3, 4] 1 second run 1 2 2 [0, 1, 2, 3, 4] 3 third round 3 3 ...

What is the method for replacing browser bundle sources using Rollup?

Is it possible to use rollup to swap out a specific source with another source in an NPM package when creating a browser bundle? The source in question is loaded dynamically using import('./relativeFile.js') (I need this to be replaced). I attem ...

Unable to properly delete data in Express/Postgres

After developing a Kanban board using JavaScript without any frameworks on the front end, I integrated Express/Postgres on the back end. However, I am encountering an issue with the 'Delete' operation. While all other CRUD operations are functio ...

What is the process for eliminating transparency from the overlay feature while utilizing Dojox/Standby?

Currently, I'm using a spinner image to indicate loading while retrieving data from the backend. However, the spinner widget creates a translucent overlay over the control. Is there a way to disable this translucency so that only the spinner is visibl ...

Determine the exact width of text without rounding in Javascript

I'm facing an issue with a div element that I'm manipulating using Javascript to change its position. The problem is that it's rounding off incorrectly. #hi{ background-color: blue; width: 2px; height: 10px; position: absolu ...

The error message that you are seeing is indicating that the `contracts` property of `this.state

Despite having encountered this issue before, I am still struggling to find a solution. The code snippet for fetching data is as follows: async componentDidMount(){ try { const res = await fetch('https://example.com/data.json'); ...

What is the best way to iterate through an array containing multiple objects in order to create a graph?

My API response contains multiple objects organized in an array: [{"symbol":"AAPL","date":"2020-02-27","adj_close":68.24}, {"symbol":"TSLA","date":"2020-02-27","adj_close":133.8}, {"symbol":"TSLA","date":"2020-02-28","adj_close":122.3}, {"symbol":"AAPL" ...

Manipulate the url bar using ajax and window.location

When making an AJAX request using .load, everything works perfectly. However, there is an issue with the URL bar. I am trying to change the URL displayed in the bar. For instance, when the ajax loads the about/contact page, I want the URL bar to show about ...

Errors in Chartist.js Data Types

I am currently using the Chartist library to monitor various metrics for a website, but I have encountered some challenges with the plotting process. The main errors that are appearing include: TypeError: a.series.map is not a function TypeError: d.normal ...

Is it time to use the JavaScript preload() function?

When I initially select a radio button, I experience a brief freezing effect. However, upon selecting them a second time, everything operates smoothly. I suspect this is due to the radio buttons being stored in the browser cache. Is there a way to preloa ...

Add a border to the navigation bar item to indicate the current page being displayed

This section shows the current navigation bar item https://i.sstatic.net/6RAGJ.png This is the desired outcome when clicking on the tab https://i.sstatic.net/8nFeB.png Uncertain about the best approach for achieving this. I have attempted to submit a val ...

Using Javascript and jQuery to validate strings within an array

My existing jQuery code works perfectly by returning true if it matches the specified name. jQuery(function($) { var strings = $(".user-nicename").text(); if (strings === "name1") { $('.mention-name').hide(); $('.se ...

What is the best way to present sorted items on a user interface?

I have a unique Med interface containing properties like drugClass, dosage, and name. Using this interface, I created an array of drugs with different attributes. How can I filter this array by drugClass and then display the filtered data on a web page? ...

In search of a highly efficient webservices tutorial that provides comprehensive instructions, yielding successful outcomes

I've reached a point of extreme frustration where I just want to break things, metaphorically speaking, of course. For the past week, I've been trying to learn how to create a web service using C# (whether it's WCF or ASMX, I don't rea ...

Tips for extracting the URL from a JSP using JavaScript

When my JSP returns, it loads a JavaScript that serves as a form action when a button is clicked. This JavaScript includes a request.open() call, with the URL it needs to pass as a peer of the JSP that loaded it. The URL must be the one that was originally ...

Detecting Collisions in a Canvas-Based Game

As part of my educational project, I am developing a basic shooter game using HTML5 canvas. The objective of the game is to move left and right while shooting with the spacebar key. When the bullets are fired, they travel upwards, and the enemy moves downw ...