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

JS tracker calls callback too early #17780

Closed
SassNinja opened this issue Jul 16, 2021 · 6 comments
Closed

JS tracker calls callback too early #17780

SassNinja opened this issue Jul 16, 2021 · 6 comments
Labels
answered For when a question was asked and we referred to forum or answered it.

Comments

@SassNinja
Copy link

Expected Behavior

I expect when I provide a callback to trackEvent, it's called AFTER the tracking is done meaning there's no pending request.

Current Behavior

When I pass a callback to trackEvent and immediately redirect the user once it's called, the request to matomo is still pending and therefore never finished.

matomo_callback_issue

Possible Solution

Not sure, where exactly the origin of that problem comes from.
After digging into the code I haven't found anything suspicious though the result is definitely wrong.
I assume it's related to this part in the code:

callback({request: request, trackerUrl: configTrackerUrl, success: true, xhr: this});

Steps to Reproduce (for Bugs)

  1. create a promise, track an event and pass the resolver as callback
  2. wait until the promise is resolved (meaning the callback is called) and the redirect to another page
  3. expect the matomo request being finished in the network panel in the browser dev tools
const trackEvent = () => {
  return new Promise(resolve => {
    window._paq.push(['trackEvent', 'category', 'action', undefined, undefined, undefined, resolve])
  })
}

const redirect = async () => {
  await trackEvent()
  console.log('expect matomo request being finished')
  window.location.href = 'https://...'
}

redirect()

Context

I'm redirecting the used to another website once he's done with a renewal. Therefore I cannot track anything on the target page but must track it right before redirecting him. This means I need to know when the matomo request is done to be sure everything is tracked before the current page is left.

Your Environment

  • Matomo Version: latest (4.3.1)
  • PHP Version: 7.4.20
  • Server Operating System:
  • Additionally installed plugins:
  • Browser: Chrome
  • Operating System: Mac OS
@SassNinja SassNinja added the Potential Bug Something that might be a bug, but needs validation and confirmation it can be reproduced. label Jul 16, 2021
@SassNinja
Copy link
Author

One addition (to prove it's a timing issue):
When I just wait a bit after the tracking (but before redirecting) it's working as expected, meaning no more pending matomo request.

const justWait = () => {
  return new Promise(resolve => {
    setTimeout(resolve, 1000)
  })
}

const redirect = async () => {
  await trackEvent()
  await justWait()
  // all good when redirecting now
}

@sgiehl
Copy link
Member

sgiehl commented Jul 16, 2021

@SassNinja Maybe you need to disable the usage of sendBeacon in that case. This is used by default (if available), and as far as I know doesn't provide the possibility to execute a callback when finished. So we trigger the callback if sendBeacon returns true, which means the browser queued the request (and thus confirms the request will be sent before the unload event)

@tsteur
Copy link
Member

tsteur commented Jul 18, 2021

@SassNinja as @sgiehl this is currently expected behaviour as when using sendBeacon the requests are sent in the background by the browser and we can't know when the request is finished. The request will generally still finish and a callback is in many cases not needed (or it is not needed to wait for the request to finish) in most cases.

I'll close this issue for now as there isn't really anything we can do. If it's important to wait for the request to finish before redirecting or so then you can disable send beacon using _paq.push(['disableAlwaysUseSendBeacon']). Generally, because the request will basically always finish when using sendBeacon, it should be fine to redirect the user directly.

@tsteur tsteur closed this as completed Jul 18, 2021
@tsteur tsteur added answered For when a question was asked and we referred to forum or answered it. and removed Potential Bug Something that might be a bug, but needs validation and confirmation it can be reproduced. labels Jul 18, 2021
@SassNinja
Copy link
Author

SassNinja commented Jul 27, 2021

@sgiehl thanks for the hint!

I was a bit confused that the following didn't work

window._pag.push(['alwaysUseSendBeacon', false])

However calling the method disableAlwaysUseSendBeacon has worked so I'm happy

@SassNinja
Copy link
Author

@tsteur thanks for the explanation!

callback is in many cases not needed (or it is not needed to wait for the request to finish) in most cases

yeah, seems my case is special due to the redirect immediately after the event is dispatched (what I cannot change)

so then you can disable send beacon using _paq.push(['disableAlwaysUseSendBeacon'])

oh I see, that looks better than my approach (which I did because push(['alwaysUseSendBeacon', false]) didn't work)

const asyncTracker = window.Matomo.getAsyncTrackers()[0]

asyncTracker.disableAlwaysUseSendBeacon()

@MatomoForumNotifications

This issue has been mentioned on Matomo forums. There might be relevant details there:

https://forum.matomo.org/t/wait-for-matomo-request-to-finish-callback-event/45875/9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
answered For when a question was asked and we referred to forum or answered it.
Projects
None yet
Development

No branches or pull requests

4 participants