question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Provide onInvalidate to register callbacks to call when Watcher gets updated (invalidated)

See original GitHub issue

What problem does this feature solve?

Sometimes inside a Vue reactive context (Watcher) you have to read data from an external source. You might have to manage resource consumption of that external source so a way to know when is current has been notified of an update in a dependency is useful because you could cancel the external source. If current watcher is already pending a run there is no point in waiting for an external source to notify as well.

I have encountered this problem when I was implementing a reactive time formatting functions. In that case I setup a timeout until the next update to the formatted string (if currently timestamp is displayed as 1 hour ago the next update is in one hour to display 2 hours ago). But if something else triggers an update (like timestmap changing in the source) there is no point in that timeout to still be around. So ideally, that timeout should be cleared. But there is no way for that currently.

I could implement this with a reactive data source which I would modify every second and then in the formatting function use the data source to compute the formatted string. But that would be very inefficient because it would rerun that formatting function every second when it would have to be rerun only in an hour. I could design it so that every formatting call registers its own data source which is updated only at a particular interval, but managing that would be very complex because it would not really be at regular intervals but the interval changes (for example, when string gets changed from 59 minutes ago to 1 hour ago).

What does the proposed API look like?

I would suggest Watcher gets a concept of invalidated state. That state would be set to true on the first update() on the watcher and reset back to false on the first next get(). If update() is called multiple times before get() is called, watcher continues to be in invalidated==true state.

Having that concept, I would suggest Vue.util.onInvalidate(callback) function which would register a callback for the current watcher context (Dep.target). That callback would be called when watcher gets invalidated (the first time update() is called). If during onInvalidate is called on a watcher which is already invalidated, the callback would be called immediately.

Any callback is called only once. You have to re-register them by calling onInvalidate again if you want to get it called again.

Moreover, on watcher teardown, any pending onInvalidate callbacks would be called as well.

I have implemented this API inside this package, but I would prefer if it was added to the official API.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
yyx990803commented, Feb 18, 2019

It’s not - will probably be in the next minor

0reactions
mitarcommented, Feb 18, 2019

I would avoid providing an overly complicated API just so that we can cater to cases where the majority of users probably won’t ever encounter, especially when you’ve managed to implement it in userland.

I managed to implement it by monkey-patching Vue. I do not think this is very nice.

If you believe the API you are proposing does solve a common problem that the return callback API cannot deal with

Oh, this is already supported?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Computed and Watch - Vue.js
The effect function receives an onInvalidate function that can be used to register an invalidation callback. This invalidation callback is ...
Read more >
Vue 3 Composition API - watch and watchEffect - This Dot Labs
The callback function we passed into watchEffect now has an argument - onInvalidate . This function also takes a callback as an argument,...
Read more >
Vue watch TypeScript error TS2769: No overload matches this ...
function watch<T>( source: WatcherSource<T>, callback: ( value: T, oldValue: T, onInvalidate: InvalidateCbRegistrator ) => void, options?:
Read more >
Reactivity API: Core - Vue.js
Takes an inner value and returns a reactive and mutable ref object, ... watch() is lazy by default - i.e. the callback is...
Read more >
Automated Re-fetching | Redux Toolkit
RTK Query > Usage > Automated Refetching: cache invalidation ... fetching new data and registering new tags for the updated cached data.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found