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

TypeError: Object(...) is not a function when using createUploadLink with create-react-app #35

Closed
aeiz opened this issue Nov 8, 2017 · 20 comments

Comments

@aeiz
Copy link

aeiz commented Nov 8, 2017

I get the following error when trying to create a link using createUploadLink:
TypeError: Object(...) is not a function

@jaydenseric
Copy link
Owner

Are you on the Apollo Slack? If you are, DM me so we can investigate the error; my username is @jaydenseric.

@adamdonahue
Copy link

Having an issue using middleware, as well.

Uncaught (in promise) TypeError: Cannot read property '_subscription' of undefined
    at error (zen-observable.js:158)
    at <anonymous>

Code:

const httpLink = createUploadLink({
  uri: process.env.REACT_APP_API_URL || 'http://localhost:8001/api/'
});

const middlewareLink = new ApolloLink((operation, forward) => {
  operation.setContext(({ headers = {} }) => {
    return {
      credentials: 'include',
      headers: {
        ...headers,
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRFToken': Cookies.get('csrftoken')
      }
    };
  });
  return forward(operation);
});

const link = concat(middlewareLink, httpLink);

Aside from replacing httpLink with the upload version, is further configuration needed?

@adamdonahue
Copy link

Ah, this seems to work:

const httpLink = createHttpLink({
  uri: process.env.REACT_APP_API_URL || 'http://localhost:8001/api/'
});

const uploadLink = createUploadLink();

const middlewareLink = new ApolloLink((operation, forward) => {
  operation.setContext(({ headers = {} }) => {
    return {
      credentials: 'include',
      headers: {
        ...headers,
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRFToken': Cookies.get('csrftoken')
      }
    };
  });
  return forward(operation);
});

const link = concat(middlewareLink, httpLink, uploadLink);

@adamdonahue
Copy link

Never mind -- it doesn't actually send any file contents.

@jaydenseric
Copy link
Owner

jaydenseric commented Nov 8, 2017

@adamdonahue try this:

const authLink = new ApolloLink((operation, forward) => {
  operation.setContext({
    fetchOptions: {
      credentials: 'include',
      headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRFToken': Cookies.get('csrftoken')
      }
    }
  })
  return forward(operation)
})

const uploadLink = createUploadLink({
  uri: process.env.REACT_APP_API_URL || 'http://localhost:8001/api/'
})

const link = authLink.concat(uploadLink)

See #36 (comment).

P.S. I'm not sure 'X-Requested-With': 'XMLHttpRequest' is technically correct, because native fetch is not the same thing.

@adamdonahue
Copy link

Yeah, just saw that comment. But shouldn't the standard middleware approach continue to work? Let me give this a shot though.

@adamdonahue
Copy link

adamdonahue commented Nov 8, 2017

This worked -- and thanks for the tip on X-Requested-With. Forgot to remove that.

const middlewareLink = new ApolloLink((operation, forward) => {
  operation.setContext(({ headers = {} }) => {
    return {
      fetchOptions: {
        credentials: 'include',
        headers: {
          ...headers,
          'X-CSRFToken': Cookies.get('csrftoken')
        }
      }
    };
  });
  return forward(operation);
});

const link = concat(middlewareLink, uploadLink);

@jaydenseric
Copy link
Owner

@aeiz any updates on the error?

@adamdonahue
Copy link

Another issue: it appears when I receive an unhandled 403 Forbidden from an endpoint I also get the _subscription issue I mentioned above.

@jaydenseric
Copy link
Owner

@adamdonahue would you like to create a new issue for that? I'll take a look.

@aeiz
Copy link
Author

aeiz commented Nov 9, 2017

@jaydenseric sorry it took so long to respond. I wanted to verify that something wasn't amiss with my current project causing this error, so I created a new project (with create-react-app). With a freshly created app, I only installed apollo-upload-client, apollo-link, and graphql, and created a link with createUploadLink and still get the error.

@aeiz
Copy link
Author

aeiz commented Nov 9, 2017

Here's the contents of my index.js:

import React from "react";
import ReactDOM from "react-dom";
import { createUploadLink } from "apollo-upload-client";

import "./index.css";
import App from "./App";
import registerServiceWorker from "./registerServiceWorker";

const link = createUploadLink({
  // Options…
});

ReactDOM.render(<App />, document.getElementById("root"));
registerServiceWorker();

@jaydenseric
Copy link
Owner

@aeiz did you also npm install the required peer dependencies apollo-link and graphql?

@aeiz
Copy link
Author

aeiz commented Nov 9, 2017

For a test, I did:

create-react-app apollo-upload-client-test
cd apollo-upload-client-test
npm install apollo-upload-client apollo-link graphql

Then I added the import and link to my index.js:

import { createUploadLink } from "apollo-upload-client";
//...
const link = createUploadLink({
   // Options…
});

Then ran npm start and get the error.

@aeiz
Copy link
Author

aeiz commented Nov 9, 2017

Interestingly enough, when I copy and paste the require statements and the createUploadLink function from the module into my index.js instead of importing createUploadLink from the module, it doesn't throw the error.

@aeiz
Copy link
Author

aeiz commented Nov 9, 2017

Also just copied and pasted the contents of apollo-upload-client/src/index.mjs to a new file in my own project and that seemed to work. Perhaps it's some weirdness with my environment in resolving that module.

@jaydenseric
Copy link
Owner

Thanks for the nice reproduction steps, I can see the error too. Looking into it now.

@jaydenseric
Copy link
Owner

This is because CRA has configured webpack to load imports with extensions not recognised as JS (.css, etc.) as assets. Our module file extension is .mjs, the new standard for ESM files in Node.js. CRA has not configured this as a JS extension in webpack. There is a CRA PR, but it does not seem to be working so maybe it has not shipped yet?

Closing because this is a third party webpack configuration issue and ultimately not an issue with apollo-upload-client.

@aeiz
Copy link
Author

aeiz commented Nov 10, 2017

@jaydenseric, Thanks for looking into this!

For others that are trying to use this with create-react-app until mjs is added, you can import apollo-upload-client like this:

import { createUploadLink } from "apollo-upload-client/lib/main";

@aeiz aeiz changed the title TypeError: Object(...) is not a function when using createUploadLink TypeError: Object(...) is not a function when using createUploadLink with create-react-app Nov 10, 2017
@RitikDua
Copy link

RitikDua commented Aug 8, 2020

In the newer version setContext is imported as

import { setContext } from '@apollo/client/link/context';

Hence ,


const authLink = setContext((_, { headers }) => {
  // get the authentication token from local storage if it exists
  const token = localStorage.getItem('token');
  // return the headers to the context so httpLink can read them
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    }
  }
});

ref: from docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants