Apollo-link: zen-observable import breaks queries in apollo-client when transpiled

Created on 15 Nov 2017  ·  34Comments  ·  Source: apollographql/apollo-link

Hi there!

I'm working to get a new project set up with Apollo Client, Apollo Link, babel, and webpack. I use a pretty simple project template to set it up with the documented suggestions in Apollo Client. When I go to run it and send it a query, I get a runtime exception and queries cannot go through. I traced this to how the zen-observable package is imported.

Intended outcome:

Apollo Client can make a query using Apollo Link, using the following code:

import { ApolloClient } from "apollo-client"
import { HttpLink } from "apollo-link-http"
import { InMemoryCache } from "apollo-cache-inmemory"
import { gql } from "graphql-tag"

const graphqlClient = new ApolloClient({
        link: new HttpLink(),
        cache: new InMemoryCache(),
})
graphqlClient.query({ query: gql`query { counter { count } }` })
        .then(console.log)
        .catch(console.error)

Actual outcome:

Apollo Client throws the following exception:

TypeError: _super.call is not a function
Stack trace:
ObservableQuery@webpack-internal:///16:56:21
QueryManager</QueryManager.prototype.watchQuery@webpack-internal:///94:404:16
QueryManager</QueryManager.prototype.query/resPromise<@webpack-internal:///94:431:20
QueryManager</QueryManager.prototype.query@webpack-internal:///94:429:26
ApolloClient</ApolloClient.prototype.query@webpack-internal:///93:102:16
@webpack-internal:///59:14:1
[59]@http://host/assets/client.js:16:1
__webpack_require__@http://host/assets/manifest.js:713:12
fn@http://host/assets/manifest.js:118:20
[49]@http://host/assets/client.js:7:18
__webpack_require__@http://host/assets/manifest.js:713:12
webpackJsonpCallback@http://host/assets/manifest.js:26:23
@http://host/assets/client.js:1:1

The ObservableQuery imports the Observable from the Apollo Link project, which imports it from the zen-observable package. When transpiled to JavaScript, the apollo-link package has this at lib/index.js:

import * as Observable from 'zen-observable';
export { Observable };

It seems that this causes some strange case when transpiling and later subclassing this Observable, but this seems to be where the call method stops being available through my investigation.

How to reproduce the issue:

Attached is a test project which should demonstrate the issue. I assume Node.js v6 or v8 installed with Yarn. Test Project

  1. Unzip and cd into the test project
  2. yarn install
  3. yarn run start and open http://localhost:3000/
  4. You should see the error shown above in the console.

You can workaround this by changing node_modules/apollo-link/lib/index.js:3 from:

import * as Observable from 'zen-observable';

to:

import Observable from 'zen-observable';

The problem is if you make this change in the corresponding .ts file, it causes a linting failure, and I'm not sure how best to resolve that.

There is this issue on StackOverflow which suggests that other people are having this issue.

Thank you so much for your time, for looking at my bug report, and for the awesome work on Apollo!

bug

Most helpful comment

I am so struggling that I have no choice but to use the following hack to get around with this issue...

webpack.config.js

      {
        test: /node_modules\/apollo-link.*?\/lib\/.*?.js/,
        loader: 'string-replace-loader',
        options: {
          search: 'exports.Observable = Observable',
          replace: 'exports.Observable = Observable.default'
        }
      },

I really wish I can get some helps here so i can remove this hack...

P.S. I do not use TypeScript but just babel. Not sure if this is the reason why it is broken to me

All 34 comments

I have a same problem but with difference error.

My code is here.

import 'isomorphic-fetch'
import { ApolloLink } from 'apollo-link'
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'

export default new ApolloClient({
  link: new HttpLink({ uri: 'http://localhost:5000/api/graphql' }),
  cache: new InMemoryCache()
})
Uncaught (in promise) TypeError: _apolloLink.Observable is not a constructor
    at HttpLink.eval [as request] (httpLink.js:98)
    at eval (link.js:60)
    at ApolloLink.eval [as request] (ApolloClient.js:30)
    at ApolloLink.eval [as request] (link.js:59)
    at execute (link.js:94)
    at eval (QueryManager.js:134)
    at new Promise (<anonymous>)
    at QueryManager.mutate (QueryManager.js:129)
    at ApolloClient.mutate (ApolloClient.js:109)
    at Header.componentDidMount (index.js:53)

I tried this work arround and I got same error with @stevestreza 's one.

```js
import 'isomorphic-fetch'
import * as apolloLink from 'apollo-link'
import Observable from 'zen-observable'
apolloLink.Observable = Observable
````

@stevestreza @mizchi what versions of apollo-client and apollo-link are you using?

Same problem here, with [email protected] in a webpack project, fixed by removing the * as in the import statement, as @stevestreza pointed out.

Same issue here.

Same here, and would like to add the issue isn't within Webpack, as written on SO, but in Apollo and/or TypeScript.

Reason I know is that I am using Rollup to create a bundle instead of Webpack.

I think this is a TypeScript + Rollup bug but I'm surprised it isn't manifesting in our own Rollup builds. Would anyone here be up to opening a pull request making the change suggested above?

Same issue here with Rollup. I'm not using Typescript either.

Looks like TS is all screwed up. I tried building the module to fix the errors but was getting TS errors.

Hello pardon my asking but does anyone have a hotfix while this is being resolved? any idea what the last stable version was?

in my investigations so far i think this problem only occurs outside of create-react-app. so there is some implicit assumption inside create-react-app that is not being documented that is causing this _super.call is not a function issue.

Same issue here, I just followed the doc on a brand new project and got this error. I'm unable to continue with Apollo.

just linking my other issue here: https://github.com/apollographql/apollo-client/issues/2785#issuecomment-354169337 where there is a proposed fix (i have not tested)

not sure if this is related but...

im using rollup to create a bundle for a very simple react app. everything is working fine until i try to introduce apollo-client into the mix..

following the documentation here: https://www.apollographql.com/docs/react/basics/setup.html#installation

after trying to build the project with rollup i get the following error during the build:

of is not exported by node_modules/zen-observable/index.js
47:         return new ApolloLink(function (operation, forward) {
48:             return (firstLink.request(operation, function (op) {
49:                 return nextLink.request(op, forward) || Observable.of();
                                                                       ^
50:             }) || Observable.of());
51:         });
node_modules/apollo-link/lib/link.js
of is not exported by node_modules/zen-observable/index.js
48:             return (firstLink.request(operation, function (op) {
49:                 return nextLink.request(op, forward) || Observable.of();
50:             }) || Observable.of());
                                 ^
51:         });
52:     }
node_modules/apollo-link/lib/link.js
of is not exported by node_modules/zen-observable/index.js
74: export { ApolloLink };
75: export function execute(link, operation) {
76:     return (link.request(createOperation(operation.context, transformOperation(validateOperation(operation)))) || Observable.of());
                                                                                                                                 ^
77: }

ive tried changing the import in node_modules/apollo-link/lib/link.js to import Observable from 'zen-observable'; as suggested in the related issue above but it does not seem to fix the issue.

I am facing an issue with zen-observable which is quite different. please have a look at
https://github.com/apollographql/apollo-link/issues/389
and suggest if I am doing something wrong.

I am so struggling that I have no choice but to use the following hack to get around with this issue...

webpack.config.js

      {
        test: /node_modules\/apollo-link.*?\/lib\/.*?.js/,
        loader: 'string-replace-loader',
        options: {
          search: 'exports.Observable = Observable',
          replace: 'exports.Observable = Observable.default'
        }
      },

I really wish I can get some helps here so i can remove this hack...

P.S. I do not use TypeScript but just babel. Not sure if this is the reason why it is broken to me

I get the same error without typescript and I can vouch that making the change

import * as Observable from 'zen-observable';
to:
import Observable from 'zen-observable';

fixes the issue

damn @kinyat i had no idea you could do that with webpack. TIL!!! thank you!!!

Same issue in a basic Hello World app with react-apollo and parcel-bundler. Any legal solution ?

@alapini I think one of the "legal" solutions is for Apollo to provide non-typescript user (i.e. Babel) a ES5 version from the ts complier.

I'm using apollo for my vuex-orm-apollo plugin and changing files within the node_modules is not a viable option for me. A soon bugfix would be really nice! :)

with the latest version of typescript the imports can be expressed in normal es modules syntax, so maybe if we all wait for Apollo to upgrade the typescript version this will work out of the box for us non TS users.

I think I'm running into some of the same issues listed here. First time using apollo, so I am not 100% sure if I'm connecting things correctly. I'm using rollup without typescript with inferno.

The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten
The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten
The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten

'of' is not exported by 'node_modules/zen-observable/index.js'
'of' is not exported by 'node_modules/zen-observable/index.js'
'of' is not exported by 'node_modules/zen-observable/index.js'

(node:37350) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: 'print' is not exported by node_modules/graphql/language/printer.js
(node:37350) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code

For those using parcel.js, this PR seems to temp fix the issue: https://github.com/parcel-bundler/parcel/pull/530

I haven't dived too deep into this problem, but it seems that the core of the issue, as @fathyb notes here, is:

The Babel current behaviour is totally correct and respects the ES6 spec. Importing a default export with a wildcard is illegal, so the errors here are legit.

However, people (#418) and libraries (antd, @blueprintjs/core, etc..) are still relying on this. The idea is to be more tolerant by relaxing the spec on exotic namespaces.

So it seems that the workaround @stevestreza posted (removing * as) is a legitimate fix for apollo-link, no?

Fwiw, I was getting the _apolloLink.Observable is not a constructor error, and it goes away if I use the above noted parcel.js PR (or revert to parcel.js 1.2.1 as noted in apollo-client/issues/2785)

I'm having this issue as well using Rollup in a Vuejs project.

thanks for sharing @tadas412

The above PR was published in 1.2.0. Let me know if it still isn't resolved!

still getting an error with 1.2.0 😢

TypeError: _super.call is not a function
    at new ObservableQuery
    at QueryManager.watchQuery 
    at eval 
    at new Promise 
    at QueryManager.query 
    at ApolloClient.query
    at VueComponent.created

this seems to be tracked here apollographql/apollo-client/issues/2785 as well

For me, it works with 1.2.0.

@littletower That may sound stupid, but are you sure, you're using 1.2.0? Maybe delete the node_modules dir and reinstall the packages? Just asking :)

@phortx yeah I did that already :(
I might add that I'm using subscriptions, don't know if that changes anything

@littletower That's odd. I was getting the same error with 1.1.0 and 1.2.0 seemed to resolve it. apollo-client has a dependency on apollo-link, so it may be that its dependency did not update. Can you create a reproduction repo?

The change definitely fixed the actual code-level issue, but it looks like yarn is causing a conflict.

  • When I use npm install to install the dependencies, it loads apollo-link 1.2.0 without any change from apollo-client. This works great and the reported issue no longer happens. (You have to manually install graphql-tag and remove the braces in the import in src/client/index.js to verify this)
  • When I use yarn install, it installs version apollo-link 1.0.0. When I yarn add apollo-link to explicitly install 1.2.0, the version in node_modules/apollo-link becomes 1.2.0, but another version of apollo-link 1.0.0 is installed at node_modules/apollo-client/node_modules/apollo-link.

I'm past my knowledge at this point on how yarn works to fix this (I would expect it to have installed apollo-link 1.2.0, not 1.0.0). I would guess that the "right" fix is to require apollo-link 1.2.0 in the package.json for apollo-client. I'll drop a note in apollographql/apollo-client#2785.

Either way, though, this seems fully fixed here!

@evans I created a repo for reproduction and guess what? I'm not having the issue, but in my original code I still do... I'll investigate further. Thanks for the feedback!

I'm getting the same error in a Polymer 3 project and apollo-boost:

import { HttpLink } from 'apollo-link-http';

causes

Uncaught SyntaxError: The requested module '../../zen-observable/index.js'
                      does not provide an export named 'default'

@heruan Did you find any solution? I am facing the same issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zsolt-dev picture zsolt-dev  ·  4Comments

MoonTahoe picture MoonTahoe  ·  3Comments

NicholasLYang picture NicholasLYang  ·  4Comments

ash0080 picture ash0080  ·  4Comments

j3ddesign picture j3ddesign  ·  3Comments