The non-nullable field Mutation.create in typegraphql with bcrypt must not be null, cannot be returned as null

Recently, I have been experimenting with typegraphql alongside apollo-server, typeorm, and bcrypt in typescript. I encountered a peculiar issue when running the mutation query using the resolver below. The error 'Cannot return null for non-nullable field Mutation.create' keeps popping up, even though the data is successfully saved to the database with a hashed password (confirmed via console.log). Strangely, the error only occurs when executing the mutation query in the browser.

Here is the mutation resolver snippet:

@Mutation(returns => Users)
create(@Arg("newuser") newuser: UserInput): Promise<Users> | any {
  bcrypt.hash(newuser.loginpassword, 12)
  .then( hash => {
      const new_user = this.usersRepository.create(newuser);
      new_user.loginpassword = hash;
      return this.usersRepository.save(new_user);
    });
}

Interestingly, when the lines related to bcrypt are commented out as shown below, no errors are thrown (although the password remains unhashed):

@Mutation(returns => Users)
create(@Arg("newuser") newuser: UserInput): Promise<Users> | any {
  // bcrypt.hash(newuser.loginpassword, 12)
  // .then( hash => {
      const new_user = this.usersRepository.create(newuser);
      //new_user.loginpassword = hash;
      return this.usersRepository.save(new_user);
    //});
}

In both scenarios, the mutation successfully creates and saves the record, and hashing with bcrypt works fine too.

I've been struggling with this issue for the past couple of weeks, scouring through similar threads such as this one (Graphql, node.js and sql,Cannot return null for non-nullable field).

  1. In the initial version (with bcrypt code), what could be causing the error? I've experimented with changing the return type to Users | any from Promise | any, and introducing another .then statement to return the Users object instead of a promise object?

  2. In Graphql, node.js and sql,Cannot return null for non-nullable field, Mr. Benjie suggests looking into . However, I'm uncertain about how to implement a nullable Mutation.create. Can anyone offer guidance or provide an example?

  3. If I define the return declaration of create as 'Promise<Users>' instead of 'Promise<Users> | any', typescript complains and expects a return statement. But adding a return statement at the end causes create to exit prematurely. Is declaring the return type as 'Promise<Users> | any' the correct approach?

Appreciate all the help and insights.

Answer №1

It's not completely certain, but there are a few things that could be contributing to this issue.

  1. Upon reviewing your initial code snippet, it appears that the only return statement is within the callback function passed to then. As a result, the create method does not explicitly return anything.

  2. After examining the source code for typeORM, it seems that Repository.save() returns a Promise<Entity> (rather than Promise<Entity[]>) when the input is a single entity object (check Repository.ts). In this scenario, your GraphQL schema expects the mutation to return an array of users, while the resolver is returning just one user.

Consider adjusting the return type to Promise<User>

@Mutation(returns => User)
create(@Arg("newuser") newuser: UserInput): Promise<User> {
  return bcrypt.hash(newuser.loginpassword, 12)
  .then( hash => {
      const new_user = this.usersRepository.create(newuser);
      new_user.loginpassword = hash;
      return this.usersRepository.save(new_user);
    });
}

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

The Angular template is throwing an error stating that c_r1.getCatType is not a valid function

Within my Angular project (version 9.1.0), I have a class structured like this: export class Contract { contractName: string; limit: number; public getCatType(): string{ if(this.limit > 0) return 'p'; return &ap ...

Is it feasible to broaden an interface in Typescript without including a specific type?

import React from "react"; interface a_to_e { a?: string; b?: string; c?: string; d?: string; e?: string; } interface a_to_e_without_c extends a_to_e { // I want to include properties a~e except for c } function Child(props: a_to_e_without_c ...

Creating a String-Helper component using Angular and TypeScript

One issue I'm facing is that when using the german ü, ä, ö characters in HTML, they are showing up as unknown symbols. To properly display them, you can write ü as "&uuml ;" and ä as "&auml ;", and so on. However, my challenge is coming f ...

Is it possible to dynamically alter the background color of a box in Material UI using TypeScript when clicked?

I need a way to change the background color of my Box when it is clicked. I have searched for a solution but couldn't find anything that fits my needs. I tried using onClick events, but haven't found the right event to get information on the sele ...

String validation using regular expressions

Below is the code I am using to validate a string using regular expressions (RegEx): if(!this.validate(this.form.get('Id').value)) { this.showErrorStatus('Enter valid ID'); return; } validate(id) { var patt = new RegExp("^[a-zA- ...

How to enhance an input field: incorporating unique buttons within

Currently, I have an input that is supposed to resemble the following: https://i.sstatic.net/pgPgk.png To achieve this look, I've implemented the code below using Styled-Components and Font-Awesome icons: <Thing> 1 <i className="fa fa ...

How is it possible for a TypeScript function to return something when its return type is void?

I find the book Learning JavaScript to be confusing. It delivers conflicting information regarding the use of void as a return type in functions. const foo = (s: string): void => { return 1; // ERROR } At first, it states that if a function has a re ...

Deactivate the Mention and Hash tag in ngx-linkifyjs

I am currently utilizing ngx-linkifyjs to automatically convert URLs in text to clickable hyperlinks. However, I am facing an issue where it is also converting # and @ tags into links. Is there a way to prevent the conversion of # and @ while maintain ...

Adjust the transparency and add animation effects using React JS

When working on a React project, I encountered an issue where a square would appear under a paragraph when hovered over and disappear when no longer hovered. However, the transition was too abrupt for my liking, so I decided to implement a smoother change ...

Angular's HttpClient.get method seems to have trouble retrieving real-time data from a Firebase database

I have been debugging and I suspect that the error lies in this part of the code. The DataService class's cargarPersonas function returns an Observable object, but I am struggling to understand how to properly retrieve the database data and display it ...

Implementing Server-Side API Response Caching in React-Query and Next JS

My server-side rendering setup with react-query is working smoothly. I am aware that react-query stores a cache on the client side to serve data if the query key is fresh and available. Here is the code snippet depicting this setup - // pages/_app.tsx imp ...

What is the best way to convert a `readonly string[]` to a regular `string[]`?

My data setup is as follows (I am not declaring it as an enum because it is used in both TypeScript server code and non-TypeScript client code): import { enumType } from 'nexus'; export const TYPE_ENUM = Object.freeze({ H: 'H', S: ...

Conditional type/interface attribute typing

Below are the interfaces I am working with: interface Movie { id: number; title: string; } interface Show { title: string; ids: { trakt: number; imdb: string; tmdb?: number; }; } interface Props { data: Movie | Show; inCountdown ...

Using Javascript to Create Interactive Visualizations of Fourier Transform

Utilizing this particular library for performing a Fast Fourier Transform on an audio file, my next step involves visualizing the output using canvasjs. Unfortunately, I am unsure about how to proceed with this visualization. I find myself puzzled regardi ...

Using the ternary operator will always result in a TRUE outcome

Having trouble with a ternary operator expression. AssociatedItemType.ExRatedTag ? session?.data.reloadRow(ids) : this.reloadItemRows(this.prepareItemsIdentities(ids)!), The AssociatedItemType is an enum. I've noticed that const ? 1 : 2 always retur ...

Designing a contact form using Angular and Firebase

Recently delving into the world of angular and firebase, I've been working on setting up a contact form for my portfolio website. However, I'm facing some challenges in implementing this. Here's what I have so far based on a guide I've ...

The role of providers in Angular applications

After creating a component and service in my project, I followed the documentation's instruction to include the service in the providers metadata of the component for injection. However, I found that it still works fine even without mentioning it in t ...

Is there a way to enable autofill functionality if an email already exists in the database or API within Angular 12?

In order to auto-fill all required input fields if the email already exists in the database, I am looking for a way to implement this feature using API in Angular. Any guidance or suggestions on how to achieve this would be greatly appreciated. ...

Unselected default option in Angular 4's select dropdown

My goal is to use Angular to retrieve a value from a variable and display it as the first option in a select element, while keeping the rest of the options below static. The issue I am facing is that even though Angular is fetching the data successfully, t ...

I'm encountering an error in TestCafe that says "TypeError: Cannot read properties of undefined (reading 'match')". Which specific segment of my code is causing this issue?

retrieveUrlFromEmailData(emailData:any){ const emailContent = emailData.email_text; const urlPattern = /(https?:\/\/[^\n]*)/; const foundUrl = emailContent.match(urlPattern)[0]; return foundUrl } ...