TypeError: Cannot read properties of undefined (reading 'Client')

After installing the Asana npm package, npm i asana as well as type definitions, npm i @types/asana, I’m getting the below error at runtime.

TypeError: Cannot read properties of undefined (reading 'Client')

This post is the closest issue I could find to mine but the proposed solution did not work form me.

Any suggestions would be much appreciated.

Code snippet from above issue

import asana from 'asana';
const client = asana.Client.create().useAccessToken('my_token');

I import the lib this way in nodeJS
const asana = require('asana')

Can you try?

Python SDK 5.0+ (in fact even v4+, but it was considered unstable and beta and was discouraged from any production use) had a breaking change.

Invocation protocol became asana.ApiClient, is there a chance that JS SDK underwent same “upgrade”?

Thanks for the suggestions. I changed my import statement to const asana = require('asana'), which got me a little further down the road. Unfortunately, when I run the below snippet I’m getting:

ReferenceError: process is not defined

const asana = require('asana');
export const getUser = async () => {
  try {
    // Configure client with personal access token
    let client = asana.ApiClient.instance;
    let token = client.authentications['token'];
    token.accessToken = 'my_token';

    // Construct resource API Instance
    let usersApiInstance = new asana.UsersApi();
    console.log(usersApiInstance);
    let user_gid = 'me';
    let opts = {};

    // Get your user info
    await usersApiInstance.getUser(user_gid, opts).then(
      (result) => {
        console.log('Hello world! ' + 'My name is ' + result.data.name + '!');
      },
      (error) => {
        console.error(error.response.body);
      }
    );
  } catch (error) {
    console.log(error);
  }
};

Seems to be having trouble with this line

const user = await usersApiInstance.getUser(user_gid, opts);

Hi @Rick_Wallace,

What version of the node-asana client library are you using? This will help us troubleshoot your issue. Assuming you installed the library with npm can you run the npm list command in your terminal. It should show you something like:

├── asana@3.0.0

ERROR 1: TypeError: Cannot read properties of undefined (reading 'Client')

I see that the code snippet you used when you encountered this error was:

import asana from 'asana';
const client = asana.Client.create().useAccessToken('my_token');

This code sample is from the v1.X.X version of the node-asana client library. The reason why you encountered this error is because in node-asana v3.X.X the way that you initialize the client is different and it does not have a Client class hence why you received the error TypeError: Cannot read properties of undefined (reading 'Client')

SOLUTION: Utilize the appropriate sample code. You can view the sample code for the function you want to use either via:

OPTION 1: Developer Docs

OR

OPTION 2: Reference the README.md on GitHub repo of the specific version you are using
NOTE: for node-asana v1.X.X there you can view the sample code in the /samples folder of the repo

For context:

This is how you would initialize the asana client with the new node-asana client library (v3.X.X)

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

ERROR 2: ReferenceError: process is not defined

I’ll need more information about which version of the client library you are using to get a better understanding.

It looks like in this scenario you are trying to export a function that calls the Asana client to make requests. I’ve noticed that you switched between import asana from 'asana';
and const Asana = require('asana'); I am assuming you are aware of the difference between the import statement and require statement. As a note for future folks out there, if you would like to use import asana from 'asana'; you’ll need to add "type": "module" to your package.json

Here’s an example of how this setup works:

SCENARIO 1: Using import

Files in your working directory:

package.json
helper.js
main.js

package.json


{
    "type": "module"
}

helper.js

import Asana from 'asana';

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = "<YOUR_ASANA_PERSONAL_ACCESS_TOKEN>";

let usersApiInstance = new Asana.UsersApi();

export const getUser = async () => {
    let user_gid = 'me';
    let opts = {};

    return await usersApiInstance.getUser(user_gid, opts);
};

main.js

import { getUser } from "./helper.js";

console.log(await getUser());

SCENARIO 2: Using require

Files in your working directory:

helper.js
main.js

helper.js

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = "<YOUR_ASANA_PERSONAL_ACCESS_TOKEN>";

let usersApiInstance = new Asana.UsersApi();

const getUser = async () => {
    let user_gid = 'me';
    let opts = {};

    return await usersApiInstance.getUser(user_gid, opts);
};

module.exports = {getUser}

main.js

const users = require("./helper.js");

const main = async () => {
    let response = await users.getUser();
    console.log(response);
}

main();

@Rick_Wallace Could you share with us your thought process on how you utilized our node-asana client library. In ERROR 1 you used the old sample code. Was this because you had old code in place and just updated the version of the client library which then gave you this error?

@John_Vu thanks for the detailed response.

I’m using version 3.0.0

Regarding my implementation approach, I’ve tried every permutation of the examples provided in the docs (Dev Docs and README.md), including the 2 scenarios you outlined, and I’m still getting either

ReferenceError: process is not defined or
TypeError: Cannot read properties of undefined (reading 'ApiClient')

I’ve tried importing the library in the variety of ways described as well with no luck. I’m using React + TypeScript + WebPack and haven’t had any issues importing any/all other 3rd party libraries.

This is the first time we’re attempting to use the library in one of our internal apps.

Hope that helps. Please let me know if you need any more info. Thanks!

I was able to resolve the ReferenceError: process is not defined error by adding the below to my webpack.config.js file

const webpack = require('webpack');
...
new webpack.ProvidePlugin({
  process: 'process/browser',
}),

I’m now getting the expected response back from the endpoints. :raised_hands:

Thanks for your time and guidance folks! :heart:

1 Like

Hi @Rick_Wallace,

Thank you for your detailed answer. This has helped greatly.

Short Explanation: the reason why you are running into the ReferenceError: process is not defined is because this is a bug with our library for client side usage. The library should work on the server side with node.js.

You can technically get around this by editing your webpack.config.js file and letting it know about the usage of node or process

We’ve fixed this issue in our node-asana v3.0.1 release along with fixes to issues you would run into with webpack.

Long Explanation: there is code within the node-asana client library that accesses node.js’ process object (here). Since you are using the node-asana library with React on the client side you run into this issue because the browser doesn’t know what this process object is.

We’ve fixed this in v3.0.1 by adding a check for typeof(navigator) === 'undefined' || typeof(window) === 'undefined' if one of these values are not undefined we could access process object (fix)

Additionally, it seems like the latest version of webpack does not include support for node.js core modules. This means that you probably or will run into this issue if you use the latest version of webpack:

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

The node-asana client library v3.0.0 used node.js’ querystring module (here) which is apart of node.js core modules. To fix this we removed the usage of node.js’ querystring to use JavaScript’s URLSearchParams this has two benefits:

  1. Webpack issue about BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.... goes away
  2. querystring was deprecated since node v14 so we are migrating to the new use case with URLSearchParams

Testing:

1: Create a React project

npx create-react-app my-react-app

2. Navigate into the folder

cd my-react-app

3. Install latest version of node-asana (v3.0.1)

npm i asana

4. Update App.js to make an API call with Asana’s node-asana library

Example:

import React, { useState, useEffect } from 'react';
import { ApiClient, UsersApi } from 'asana';
import logo from './logo.svg';
import './App.css';

function App() {

  const [user, setUser] = useState(null);

  useEffect(() => {
    async function getUser() {
      let client = ApiClient.instance;
      let token = client.authentications['token'];
      token.accessToken = "<YOUR_ASANA_ACCESS_TOKEN>";
    
      let usersApiInstance = new UsersApi();
      let user_gid = "me";
      let opts = {
        "opt_fields": "name"
      };
    
      await usersApiInstance.getUser(user_gid, opts).then((result) => {
        setUser(JSON.stringify(result.data, null, 2));
      }, (error) => {
        console.error(error.response.body);
      });
    }
    getUser();
  });

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <div>{user}</div>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

NOTE: Take note of the import statement in this example for future use cases import { ApiClient, UsersApi } from 'asana';. Also, I am not a React expert so forgive me for any React taboos that I might be breaking with my code.

  1. Start React app
npm start
  1. Observe successful API call