Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class constructor DataSource cannot be invoked without 'new' using Babel #2216

Closed
vaskaloidis opened this issue Jan 23, 2019 · 12 comments
Closed

Comments

@vaskaloidis
Copy link

I created my own Custom DataSource class using Knex as the backend, but I keep getting this error about my call to the DataSource superclass: Class constructor DataSource cannot be invoked without 'new' using Babel

I read the previous issues pertaining to this error, and everybody solved it by simply upgrading to es6+ but I am using the latest ECMA and it is still happening.

The issue is with the super() here:

const { DataSource } = require("apollo-datasource");
class RoleAPI extends DataSource {
  constructor(database) {
    super(); // Line referenced throwing the the error
    this.database = database;
  }
  initialize(config) {
    this.context = config.context;
  }
  async getAllRoles() {
    const roles = await this.database("auth_role").select("name");
    return roles;
  }
}
module.exports = RoleAPI;

For reference, here is my server definition:

import database from "./common/database";
import UserAPI from "./resolvers/datasources/user";
import RoleAPI from "./resolvers/datasources/role";
const dataSources = () => ({
  roleAPI: new RoleAPI(database),
  userAPI: new UserAPI(database)
});
const app = express();
const server = new ApolloServer({
  typeDefs,
  resolvers,
  dataSources,
  playground: GQL_PLAYGROUND,
  introspection: GQL_INTROSPECTION
});

Here is the DataSource's usage:

const { GraphQLScalarType } = require("graphql");
const { Kind } = require("graphql/language");
const resolvers = {
  Role: {},
  Query: {
    roles: async (parent, args, datasources) =>
      datasources.roleAPI.getAllRoles
  }
}

I am running @babel/core, @babel/runtime @babel/node and "@babel/preset-env" all ~7.2.0 - still to no avail. Also the error is returned when I try and run queries in the Playground - queries that previously worked until I setup the DataSource. Instead of the data, it returns the error about the call to super(). Nothing in the console.

@vaskaloidis
Copy link
Author

For anyone that runs into this problem - I solved it by adding this to my .babelrc file and it seems to have fixed it.

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "current"
        }
      }
    ]
  ],
  "plugins": ["@babel/plugin-transform-runtime"]
}

@mschipperheyn
Copy link

Did not solve it for me :-(

@abernix
Copy link
Member

abernix commented Feb 4, 2019

@vaskaloidis Yes, this can be avoided by not transpiling classes in your own user code which extend the native classes provided by RESTDataSource. The mixture of compiled and native classes has been historically difficult, but modern versions of Node.js support native classes, so this would seem to be a result of over-transpiling code which could benefit from the native ECMAScript class support provided in modern Node.js versions.

@mschipperheyn Do you have a Babel configuration in place that you could share? What version of Node.js are you using?

@mschipperheyn
Copy link

@abernix I fixed this using babel.config.js:

process.env.BUILD_TARGET === 'client'
			? [
				require.resolve('@babel/preset-env'),
				{
					modules: false,
				},
			  ]
			: [
				require.resolve('@babel/preset-env'),
				{
					targets: {
						node: 'current',
					},
					exclude: [
						'babel-plugin-transform-classes',
						'@babel/plugin-transform-classes',
					],
					modules: false,
				},
			  ];

@lopezlean
Copy link

@vaskaloidis As you said, adding:

    {
      "targets": {
        "node": "current"
      }
    }

Solved the problem

This is my .babelrc:

{
  "presets": [
    [
    "@babel/preset-env",
    {
      "targets": {
        "node": "current"
      }
    }
  ]
  ],
  "plugins": ["@babel/plugin-proposal-object-rest-spread"],
  "sourceMaps": "inline",
  "retainLines": true
}

@keepitsimple
Copy link

I successfully solved this issue with babel-preset-latest-node

My .babelrc:

{
  "presets": [["latest-node", { "target": "current" }]]
}

@martijnwalraven
Copy link
Contributor

Closing this because the issue has been solved above.

@ilan-schemoul
Copy link

How do I do if I'm using the typescript compiler ?

@ahouzzer
Copy link

@NitroBAY same question here

@koorosh
Copy link

koorosh commented Nov 27, 2019

@NitroBAY , @ahouzzer , here is solution for TS:
#1388 (comment)

johnnyoshika added a commit to johnnyoshika/messenger-graphql that referenced this issue Jan 16, 2020
Without this, we'll get a 'Class constructor JSONPlaceholder cannot be invoked without 'new'' error message

Source: apollographql/apollo-server#2216 (comment)
@vidz1979
Copy link

vidz1979 commented Mar 3, 2021

To future readers: I solved this problem setting target and moduleResolution in tsconfig.json like this...

{
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src",
    "lib": [
      "esnext"
    ],
    "strict": true,
    "esModuleInterop": true,
    "target": "ES2015",
    "moduleResolution": "node"
  },
  "include": [
    "src/**/*"
  ]
}

@dkryshtopenko

This comment has been minimized.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests