The integration between Mongoose and GraphQL does not support populating models

It seems like I have encountered a unique issue that none of the existing solutions have been able to resolve. I am running a backend server with Apollo Server + Mongoose on localhost. However, I am facing difficulties in populating or creating the collection due to the following error:

Error:

"ID cannot represent value: <Buffer 5e 38 65 18 f1 e3 f5 43 10 d4 c1 45>"
.

Below is the model I am working with:

import mongoose from 'mongoose';
const Float = require('mongoose-float').loadType(mongoose);

const gastoSchema = new mongoose.Schema({
    descripcion: String,
    importe: Float,
    proveedor: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Proveedor'
    },
}, {
    timestamps: {
        createdAt: 'fechaCreacion',
        updatedAt: 'fechaActualizacion'
    }
});

export default mongoose.model('gastos', gastoSchema);

This is the GraphQL type definition I have used:

import { gql } from 'apollo-server';

export default gql`
    type Gasto {
        id: ID
        descripcion: String
        importe: Float
        proveedor: Proveedor
    }

    extend type Query {
        gastos: [Gasto]
        gasto(id: ID!): Gasto
    }

    extend type Mutation {
        crearGasto(descripcion: String, importe: Float, proveedor: ID): Gasto
        actualizarGasto(id: ID!, descripcion: String, importe: Float, proveedor: ID): Gasto
        eliminarGasto(id: ID!): String
    }
`;

Furthermore, here is the resolver implementation:

import Gasto from '../models/Gasto';

export default {
    Query: {
        gastos: () => Gasto.find().populate('proveedores').exec(),
        gasto: (_, { id }) => Gasto.findById(id).populate('proveedores').exec()
    },
    Mutation: {
        crearGasto: (_, input) => Gasto.create(input),
        actualizarGasto: (_, input) => Gasto.findOneAndUpdate(input),
        eliminarGasto: (_, { id }) => Gasto.findOneAndDelete(id)
    }
};

Attempt 1

I made a modification to my model definition based on a suggestion, but unfortunately, it didn't resolve the issue:

import mongoose from 'mongoose';
const Float = require('mongoose-float').loadType(mongoose);
const ObjectId = require('mongoose').Types.ObjectId;

ObjectId.prototype.valueOf = function() { return this.toString(); }

const gastoSchema = new mongoose.Schema({
    descripcion: String,
    importe: Float,
    proveedor: {
        type: ObjectId,
        ref: 'Proveedor'
    },
}, {
    timestamps: {
        createdAt: 'fechaCreacion',
        updatedAt: 'fechaActualizacion'
    }
});

export default mongoose.model('gastos', gastoSchema);

Attempt 2

Following the mongoose documentation, I tried switching between populate('proveedores') (plural) and populate('proveedor') (singular), but a new error occurred:

import Gasto from '../models/Gasto';

export default {
    Query: {
        gastos: () => Gasto.find({}).populate('proveedor').exec(),
        gasto: (_, { id }) => Gasto.findById(id).populate('proveedor').exec()
    },
    Mutation: {
        crearGasto: (_, input) => Gasto.create(input),
        actualizarGasto: (_, input) => Gasto.findOneAndUpdate(input),
        eliminarGasto: (_, { id }) => Gasto.findOneAndDelete(id)
    }
};

Error:

"message": "Schema hasn't been registered for model \"Proveedor\".\nUse mongoose.model(name, schema)"
.

Just to provide complete information, here is the definition of my Proveedor model:

import mongoose from 'mongoose';

const proveedorSchema = new mongoose.Schema({
    nombre: {
        type: String,
        required: true
    },
    telefono: String,
    direccion: String,
    email: String,
}, {
    timestamps: {
        createdAt: 'fechaCreacion',
        updatedAt: 'fechaActualizacion'
    }
});

export default mongoose.model('proveedores', proveedorSchema);

Lastly, this is the GraphQL query I am using in the playground:

query {
  gastos {
    id
    importe
    proveedor {
      id
      nombre
    }
  }
}

If anyone has any insights or suggestions, I would greatly appreciate it. Thank you in advance.

Answer №1

When using mongoose.model(), the first argument should be the singular name of the collection your model represents. Mongoose will automatically search for the plural, lowercase version of your model name. Therefore, for your scenario:

mongoose.model('Expense', expenseSchema);
mongoose.model('Supplier', supplierSchema);

Afterwards, you need to include a resolver for the supplier field and add .exec() to execute the mongoose queries

import Expense from '../models/Expense';
import Supplier from '../models/Supplier';

export default {
  Expense: {
    supplier: ({ supplier }) => Supplier.findById(supplier).exec() 
  },
  Query: {
    expenses: () => Expense.find().exec(),
    expense: (_, { id }) => Expense.findById(id).exec()
  },
  Mutation: {
    createExpense: (_, input) => Expense.create(input).exec(),
    updateExpense: (_, { id: _id, ...input }) => 
    Expense.findOneAndUpdate({ _id }, input, { new: true }).exec(),
    deleteExpense: (_, { id: _id }) => Expense.findOneAndDelete({ _id }).exec()
  }
}

It's important to note that the resolver for updateExpense should be

updateExpense: (_, { id: _id, ...input }) => Expense.findOneAndUpdate({ _id }, input, { new: true }).exec()

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

Constantly showing blank white pages on my website specifically in Internet Explorer 11

I successfully developed a website using react, babel, webpack, and backend Django framework. Everything runs smoothly on Chrome, Safari, and Firefox, but when it comes to IE11, issues arise. Initially, the site functions properly, but after navigating thr ...

Issue with visibility of pagination in AngularJS ui

I am facing an issue with pagination in my AngularJS UI application. I have a dataset that requires server-driven pagination due to its size. The problem I'm encountering is that the pagination element is not displaying on the page, even though I hav ...

Storing executable scripts in HTML5 LocalStorage allows for the dynamic creation

As I work on a hybrid app with its own local HTML and JS files, there are times when I need to load additional small executable JS scripts and CSS from the server. Currently, I achieve this by using $.getScript, which has been working well. In order to ma ...

When the page initially loads, the block appears on top of the upper block and remains in place after the page is refreshed

Upon initial loading, the block appears on top of another block but remains fixed upon page refresh. The same issue occurs in the mobile version of the site and occasionally displays correctly. The website is built on WordPress and optimized using Page Spe ...

Connecting to a MongoDB or Mongoose database dynamically using Node.js

I am currently working on developing a multi-tenant application where each client will have its own dedicated database. Here is my scenario: I have created a middleware that identifies the client based on their subdomain and retrieves the necessary datab ...

How can I create a more spacious and stylish JTextField for my address bar?

I am working on developing my Java skills by creating a custom browser. Is there a way to adjust the size and shape of the address bar, which is currently implemented as a JTextField with Swing's default settings? Here is the code snippet I am using: ...

Executing shell scripts on the backend of a Node.js web application: A step-by-step guide

Currently, I have a full stack MERN application up and running on a Google Compute Engine, with a local MongoDB also running on the same server. This application is a CRUD system. However, I have a specific script stored on the server that I want to be exe ...

"Learn how to implement a feature that allows for the acceptance of string input in discord

I am struggling to find the right solution for my issue. I am trying to implement a change_nick command but unsure about what type/number option to utilize. This is how I'm creating my command: commands.create ( { ...

The function user.setPassword is not available at this time (While resetting password)

My express app uses passport for user authentication, which is working fine. However, I am facing an issue while trying to implement a password reset feature. The error message I receive is: TypeError: user.setPassword is not a function I have researched ...

Enhance the original array of a recursive treeview in VueJS

After going through this tutorial, I decided to create my own tree view using recursive components in Vue.js. The structure of the input array is as follows: let tree = { label: 'root', nodes: [ { label: 'item1', nod ...

How can I adjust the time in a range slider using AngularJS?

Currently, I am utilizing a Slider with draggable range in angular js for time selection. The Slider can be found here: https://jsfiddle.net/ValentinH/954eve2L/. I aim to configure the time on this slider to span from 00.00 to 24.00, with a 10-minute inter ...

Material UI AppBar displaying custom colors instead of theme colors

Currently, I am utilizing Material UI version 4.7.0. In my project, I have established a customized theme (shown below) by utilizing createMuiTheme() method with personalized primary and secondary colors set. Within my AppBar component (also displayed be ...

selenium.common.exceptions.WebDriverException: Message: IndexError: array index out of bounds

I've been working on creating a web scraping tool that involves a Python script and a JavaScript code. The Python script is designed to call the JavaScript code, which then extracts relevant content from a web page and sends it back to the Python scri ...

What causes the state hook in react to alter every single property within the object?

I have a list of team members and each member is associated with the same set of applications. I created 2 classes to link each member with their respective applications, resulting in a comprehensive list of all members and applications. This list was init ...

What is causing the TypeError in next-auth when attempting to destructure the 'manager' property of the 'connection' object, which is null?

I encountered an error when connecting to mongo atlas, but everything works fine with a local database. Please refer to the image of the db connection and the terminal error for additional details. dbconnect.ts import mongoose from "mongoose"; ...

What is the proper way to encode URL parameters for a REST API request?

When working on a REST API call, I needed to create some URL parameters using Angularjs 1.4.2. To achieve this, I utilized a form to pass the parameters to a service function which handles building the parameters and making the $http.post call to the API. ...

Navigating with useRouter().push() from the "next/navigation" package is not functioning as expected when used on a customized signIn page alongside next-auth

Upon logging in successfully on my custom signIn-Page using next-auth, I am facing an issue with redirecting back to the callbackUrl. The setup includes react 18.2.0, next 13.4.8-canary.2, and next-auth 4.22.1. The code for the signIn-Page (\src&bsol ...

Creating a dropdown menu utilizing JavaScript/jQuery arrays

Looking to create an HTML select menu using a JavaScript array where the keys are used as values for options. The challenge is when entering numbers as keys, they should be accepted in the code. a([selected="No of rooms", 1="1", 2="2", 3="3", 4="4", 5="5" ...

Node.js Axios Returns Bad Request with Status Code 400

I am currently facing an issue while trying to send the results of a nodejs query to an endpoint. Interestingly, I receive a successful response when using Postman with the correct parameters, but encounter errors when attempting to use axios. data: ' ...

What is the best way to delete the "Click to sort Ascending" text from the header of each column in a bootstrap-vue table?

Recently, I came across a bootstrap-vue table that caught my attention: https://i.sstatic.net/5jENs.png Below is the code snippet for the table setup: <template> <div class="container"> <h1 class="pt-2 pb-3">Bo ...