posthog-js icon indicating copy to clipboard operation
posthog-js copied to clipboard

posthog.reset() is throwing an undefined type error

Open anuraagy opened this issue 4 years ago • 8 comments

Error: TypeError: Cannot read properties of undefined (reading 'props') at PostHogLib.push.../node_modules/posthog-js/dist/es.js.PostHogLib.get_property (es.js:6492) at PostHogLib.push.../node_modules/posthog-js/dist/es.js.PostHogLib.reset (es.js:6183) at logoutUser (App.tsx:134)

anuraagy avatar Oct 19 '21 08:10 anuraagy

Hey! I'm unable to reproduce this:

Could you include information on:

  1. How you're initializing posthog
  2. Code around the reset() call?

macobo avatar Oct 28 '21 07:10 macobo

Hi @macobo ,

I'm having the same error. I'm using it on a Next.js project and I'm using posthog-js This is how I'm initializing it:

const init = (config: posthog.Config = {}): void => {
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY as string, {
    api_host: 'https://app.posthog.com',
    autocapture: true,
    ...config,
  })
}

Then I'm calling it like so:

Haven.create({
    services: [
      {
        name: 'PostHog',
        purposes: ['analytics'],
        inject: () => {
          analytics.enable()
        },
      },
    ],
    ....
  })

And this is my analytics.ts file

const enableAnalytics = (): void => {
  init()
  posthog.opt_in_capturing()
}

export const analytics = {
  enable: enableAnalytics,
}
...

This is the full error: 
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'props')
    at Nt.get_property (_app-156a83673d7d349b.js:1)
    at Nt.reset (_app-156a83673d7d349b.js:1)
    at Object.reset (_app-156a83673d7d349b.js:1)
    at 6437-1a792c11196bec46.js:1
    at l (main-910e5354fadf79f7.js:1)
    at Generator._invoke (main-910e5354fadf79f7.js:1)
    at Generator.next (main-910e5354fadf79f7.js:1)
    at n (9029-4b072a8bffa024e0.js:1)
    at s (9029-4b072a8bffa024e0.js:1)
    at 9029-4b072a8bffa024e0.js:1

alveshelio avatar Dec 16 '21 16:12 alveshelio

In this case, you can work around this by call .opt_in_capturing() in the loaded callback. See an example with identify here: https://posthog.com/docs/integrate/client/js#identifying-users

macobo avatar Dec 17 '21 09:12 macobo

Hi @macobo, could it help to mention in the documentation that the same caveat - method call right after .init() - may also apply to .opt_in_callback() as it does with .identify()?

pragunbhutani avatar Dec 21 '21 19:12 pragunbhutani

Hey guys I'm having the same issue here. The weird part is that I'm having this only in development. I tested on production and couldn't reproduce it.

This is how I'm wrapping the .reset()

 const handleLogout = () => {
    HttpClient.delete("/users/sign_out").finally(() => {
      posthog.reset()
      window.location.assign("/users/sign_in")
    })
  }

Where Http is a wrapper around the axios...

The error I'm getting:

es.js:5799 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'props')
    at __webpack_modules__../node_modules/posthog-js/dist/es.js.PostHogLib.get_property (es.js:5799:1)
    at __webpack_modules__../node_modules/posthog-js/dist/es.js.PostHogLib.reset (es.js:5552:1)
    at NavBar.tsx:105:7
    at <anonymous>

Checking the error:

PostHogLib.prototype.get_property = function (property_name) {
  return this['persistence']['props'][property_name];  // this is throwing => Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'props')
};

jramiresbrito avatar Jun 27 '22 19:06 jramiresbrito

Hey guys I'm having the same issue here. The weird part is that I'm having this only in development. I tested on production and couldn't reproduce it.

This is how I'm wrapping the .reset()

 const handleLogout = () => {
    HttpClient.delete("/users/sign_out").finally(() => {
      posthog.reset()
      window.location.assign("/users/sign_in")
    })
  }

Where Http is a wrapper around the axios...

The error I'm getting:

es.js:5799 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'props')
    at __webpack_modules__../node_modules/posthog-js/dist/es.js.PostHogLib.get_property (es.js:5799:1)
    at __webpack_modules__../node_modules/posthog-js/dist/es.js.PostHogLib.reset (es.js:5552:1)
    at NavBar.tsx:105:7
    at <anonymous>

Checking the error:

PostHogLib.prototype.get_property = function (property_name) {
  return this['persistence']['props'][property_name];  // this is throwing => Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'props')
};

It seems I was the cause of this since I was enabling the initialization only for a production environment, but I didn't do the same for development. I'll keep the comment for reference.

A simple guard did the trick.

jramiresbrito avatar Jun 27 '22 19:06 jramiresbrito

So, the capture() method has a guard that makes sure it doesn't crash if init hasn't been called:

https://github.com/PostHog/posthog-js/blob/5f2c24d8c0d31e195aeea88a7a98b698782f9863/src/posthog-core.ts#L699-L708

But the rest of the posthog methods don't. I'd say that they probably should, and that it'd also be useful to make the type-safety of that file a bunch better. The reason why this error has slipped by is because the persistence member is typed as PostHogPersistence even though it is sometimes undefined, and when it's assigned as undefined, we're using as any.

https://github.com/PostHog/posthog-js/blob/5f2c24d8c0d31e195aeea88a7a98b698782f9863/src/posthog-core.ts#L283

I think it'd be nice to do something like combining all of the parts of the posthog client that are initialized in init and putting them into one nullable object and making sure that that object is valid before proceeding in the rest of the functions. Or just making them | undefined and checking for their existence before using them.

tmcw avatar Dec 01 '22 19:12 tmcw

From my understanding.. this issue is cause by not init the posthog at the first place..?

because I am disable init on development mode..

// only run at production mode
if (process.env.NODE_ENV !== 'development') {
      posthog.init('TOKEN', {
        api_host: 'https://app.posthog.com',
      })
}
// at logout 
posthog.reset() // throw error..

zigang93 avatar Jan 09 '23 04:01 zigang93