Comments (4)
Hey @Jonashr — I might know what's going on here.
If you have transactions enabled, the transaction for updating a document will not yet have been completed by the time that you run your afterChange
hook.
And if you are awaiting your revalidate method within your afterChange
hook, Next.js would be attempting to fetch the document before the updates within the update operation's transaction are committed. That would mean that Next.js would then retrieve the data as it was before the change was made.
If you did not await your revalidation call within your afterChange
hook, Payload could continue on to commit the transaction and it could then be completed before Next.js made its fetch for the new data.. but that doesn't seem ideal to me because there could still be a potential race condition if the transaction doesn't complete before Next fetches.
Here are 2 other options to consider:
1 - You can call commitTransaction
yourself, before calling your revalidate
endpoint, by doing the following:
const { payload, transactionID } = req
await payload.db.commitTransaction(transactionID)
2 - We could make some type of adjustment to our logic so that transactions are committed either before afterChange
runs.
I am not sure if the second option would be ideal though - because some hooks might want to have logic included within their afterChange hook which should indeed be part of the same transaction (creating other documents, updating other documents, etc.)
Try number 1 for now. Does that work?
from payload.
@jmikrut @DanRibbens Thanks for the great suggestion! You were right about the transaction not being completed being the issue here. As suggested I added the code to commit the transaction:
const { payload, transactionID } = req
await payload.db.commitTransaction(transactionID)
Once I committed the transaction it worked like a charm. So I am just going to mark this issue as completed as has solved my issues. Thanks again!
from payload.
Hey @Jonashr,
Thanks for that info, this is helpful and very clear to me of what the issue is. I'll add some ideas on top of what James has already stated.
In your hook you can pass the req
which includes a transactionID to any payload local API functions or payload.db operationsto use the same transactions. In that way your payload.findByID example could work to get "ABCDEF".
You could pass your data to the validation endpoint from this fetch if you wanted one workaround option.
Another option is to add a setTimeout() this isn't great because of course you won't really know how long to wait before knowing a transaction has completed and it is ugly. If an error occurs and revalidation occurs it shoudln't be a big deal since the content of the last validation will come up again on the next query after a rollback, so probably fine.
You could disable transactions as another option. If you are using mongoDB you'd do that with transactionOptions: false. Turning this off reduces your overall data integrity so errors that come up in normal operation might leave a bad state of data changes from one request. Not ideal, but still an option.
Ideally we should have a pattern for this that would let you push callbacks after a commit. I want it to have a good DX of course, so I'm open to ideas.
from payload.
I just ran into this too. For me it was quite confusing tbh, I did not expect the afterChangeHook
to run before the changes are actually committed to the DB. After I read the source code, it made sense what was happening and your explanation confirms this.
Similarly to the op, in my use case I want to purge and prime a cache of an external app when the user has saved something in the CMS. The cache priming within the hook didn't work, as the external app would always pull the previous data from the CMS.
I understand that there may be other use cases where it is beneficial to have the transaction commit only after the hook has run. Your described solution with committing the transaction in the hook works for me well. I would appreciate a better API for this though (maybe an afterCommitHook
)?
from payload.
Related Issues (20)
- `generate:types` Fails with Endpoint in Collection Configuration HOT 1
- Text fields that contain international characters are sorted to the end
- When using role based user fields, /create-first-user form always returns "passwords do not match" HOT 2
- TypeError: Cannot assign to read only property 'visibleEntities' of object '#<Object>' HOT 2
- Non-default admin.avatar renders nothing HOT 2
- buildInitialState doesn't handle Array Field Data correctly
- WebP Upload Issue with undefined height HOT 9
- Jsonschema requires uri and filematch despite schema being directly defined
- Locale switch sometimes shows wrong locale HOT 1
- Preview button's fetch call is missing credentials: include
- List view > Filters > "is in" operator > operand value doesn't support multiple selections in Relationship fields
- HMR looping if importing from generated types HOT 1
- Multiple Local API queries in hooks will never resolve (Postgres) HOT 5
- Reset Password link redirects to sign-in page HOT 1
- Toast stuck on submitting when resetting password
- Npm projects receiving `Cannot find module 'drizzle-orm/pg-core'`
- type SelectFieldProps onChange props is typed incorrectly HOT 1
- Resizing silently fails if `sharp` is not defined in config HOT 1
- Doesn't change time from 12-hour format to 24-hour based on locale. HOT 1
- CollapsibleProvider's withinCollapsible is never true. Missing withinCollapsible related CSS classes. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from payload.