Solving automatically generated TypeScript MongoDB types for GraphQL results

Utilizing the typescript-mongodb plugin along with graphql-codegen to automatically generate Typescript types enables easy data retrieval from MongoDB and GraphQL output via Node.

The initial input schema in GraphQL format appears as follows:

type User @entity{
    id: ID @id,
    firstName: String @column @map(path: "first_name"),
...

Upon generation, the output Typescript types seem accurate:

export type User = {
   __typename?: 'User',
  id?: Maybe<Scalars['ID']>,
  firstName?: Maybe<Scalars['String']>,
...

This corresponds with the DB object structure:

export type UserDbObject = {
  _id?: Maybe<String>,
  first_name: Maybe<string>,
...

An issue arises when returning the mongo document as a UserDbObject, as the mapping of fields is not reflected in the output. One possible solution could involve creating a custom resolver to re-map the fields back to the User type, although this would entail duplicating field mappings across different areas.

For instance, without mapped fields returned by a resolver similar to this:

userById: async(_root: any, args: QueryUserByIdArgs, _context: any) : Promise<UserDbObject> => {
    const result = await connectDb().then((db) => {
      return db.collection<UserDbObject>('users').findOne({'_id': args.id}).then((doc) => {
        return doc;
      });
    })
    ...
    return result as UserDbObject;
}

Is there a method to leverage the typescript-mongodb plugin in a way that only entails schema field mapping, followed by automatic resolution using the generated code?

Answer №1

To facilitate the mapping between your GraphQL types and your models, you can leverage the mappers feature of codegen. Take a look at these resources for more information:

Since each codegen plugin functions independently without interconnectivity, you will need to manually specify the mappings, like so:

config:
  mappers:
     User: UserDbObject

By doing this, the typescript-resolvers plugin will use UserDbObject as needed (whether as a parent value or return value).

If you prefer an automated approach, you can either programmatically utilize codegen (), or create a .js file instead of a .yaml file that generates the config section based on your requirements.

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

Angular not successfully passing ID in for loop

I am trying to pass the res[i].id value to my ArrayList while maintaining the sequence. Can anyone help me understand why 809 and 806 are not getting added to the arrayList correctly? 0: {id: 0, ArrayListID: 809, VarName: "TEST001A"} 1: {id: 0, ...

I'm looking for a sample of RadPieChart for nativescript + angular. Can anyone help me out?

I'm currently working on a multi-platform application that requires a PieChart to be displayed on the main screen. Can someone point me to a comprehensive example of how to implement this? I have tried following this guide and modifying it according ...

Troubleshooting the issue of option tag failing to insert values into MongoDB with React and NodeJS

I am currently working on integrating the option value tags in my MERN project. However, I am facing an issue where nothing is being inserted into the database. As a beginner in learning MERN, I am struggling to identify the root cause of this problem. B ...

Syntax for nested arrow functions in TypeScript

const fetchAsyncData = (input: { value: string }): AppThunk => async (dispatch) => { try { const fetchedData = await getData({ input.value }); } catch (error) { console.log(error); } }; An error message is displayed stating "No value ...

The Battle of Identifiers: Named Functions against Anonymous Functions in TypeScript

When it comes to performance and performance alone, which option is superior? 1) function GameLoop() { // Performing complex calculations requestAnimationFrame(GameLoop); } requestAnimationFrame(GameLoop); 2) function GameLoop() { // ...

The object's key values were unexpectedly empty despite containing data

There's an issue with my object - it initially gets key values, but then suddenly loses them all. All the key values become empty and a message appears in the console for the object: "this value was evaluated upon first expanding. it may have ch ...

Traversing a sequence of method calls within a Promise object (as the return type)

In software development, there is a classic technique where a method returns the result of another method call: method1(): ObjectX { if( condition1 ) return method2(); return undefined // or some default value; } method2(): ObjectX { let r ...

The DB GridFS API is causing files to become corrupt when downloading .zip files

Background Information: An application built with Node.js and Loopback that requires data from legacy enterprise CRM systems to be stored in its database. The data is provided in the form of a .zip file, which needs to be saved using GridFS for production ...

Enhancing TypeScript type definitions for the Response.render() method in Express

Struggling with enhancing the type safety of my Express project by extending the Response.render function. import { Response } from "express"; import { Product } from "../models/Product.interface"; export interface ProductListResponse ...

Utilizing Vue and Typescript for efficient dependency injection

After attempting to use vue-injector, I encountered an issue as it was not compatible with my version of Vue (2.6.10) and Typescript (3.4.5). Exploring other alternatives, there seem to be limited options available. Within the realm of pure typescript, t ...

What is the best way to import a typescript file using a provided string?

I have a directory filled with JSON schemas, all coded in TypeScript. My goal is to import them collectively while preserving the typing, instead of having to write out numerous import statements. These schemas are utilized for validating JSON data being ...

TS2365: The '!== 'operator is not compatible with the types ""("" and "")""

function myFunction(identifier: string) { identifier = "("; }; let identifier: string = ")"; if (identifier !== '(') throw "Expected '(' in function"; myFunction(identifier); if (identifier !== ')') throw "Expected &a ...

Exploring potential arrays within a JSON file using TypeScript

Seeking guidance on a unique approach to handling array looping in TypeScript. Rather than the usual methods, my query pertains to a specific scenario which I will elaborate on. The structure of my JSON data is as follows: { "forename": "Maria", ...

Python fastAPI and MongoDB environment allows the return of a tuple in the BaseModel list

Currently, my setup includes env with python311, pydantic, fastapi, and mongod. return membercollection(members=await c_members.find(queryparam).to_list(1000)) This code snippet retrieves the following information: members=[membermodel(id='65b3908a77 ...

Introducing an innovative Serverless Multi-user Blogging Platform utilizing Next.js, Tailwind, and AWS CLI for seamless content creation and management

Seeking assistance as I may have overlooked a step. Any guidance is appreciated! Recently, I managed to deploy a full-stack serverless nextJs application on AWS Amplify successfully. I made modifications by adding a new field while creating a new blog pos ...

The Vue data retrieved from an API using onMounted() is not initially showing up in the DOM. However, it magically appears after I make changes to the template

Hello and thank you to those taking the time to read this. I am new to Vue, so I may be overlooking something obvious here, but after being stuck for several days, I am reaching out for help. In my SFC file, I have an onMounted function fetching data from ...

Filtering based on the date, ignoring the timestamp portion

I am looking to display my blog posts in a paginated manner based on their creation date. For example, I want to have a page for 5 posts written on 2012-10-01, another page for 11 posts written on 2012-10-03, and no page at all for 2012-10-02 since there a ...

Angular - developing a custom web element to enhance the project

Is there a way to convert a single module into a web component and integrate it within the same project? Specifically, I have 3 modules in my project and I am looking to transform only module1 into a web component and incorporate it seamlessly. Thank you! ...

Using a function to update a field in each document within MongoDB

I am in the process of updating all my existing documents and encrypting sensitive information. I have created a script in my code to specifically encrypt the "name" field in each document: const update = await User.updateMany( {}, { $set: ...

Unable to connect to MongoDB from within a Docker container

I am currently in the process of containerizing my application within Docker. I have two separate images, one for my node application and another for MongoDB. These two have been linked using Docker Compose. However, whenever I attempt to access MongoDB in ...