-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
DataStore.save failed to update values for newly created record #12729
Comments
Hi @sjdeak , thanks for raising this issue. However, I was not able to reproduce the issue on the latest version of aws-amplify (v6.0.8). Looks like you're on 6.0.6 but I wasn't able to reproduce the issue when I downgraded either so you can upgrade but that wouldn't fix the issue. Might be configuration related. Can you run If it is enabled, what Conflict Resolution Strategy are you using? (ex. Auto Merge, Optimistic Concurrency, etc) |
One thing I did notice though, is that the very first time I created a Afterwards, I was seeing the Not representative of the issue, but I thought that was interesting. |
Hi @chrisbonifacio Many thanks for the rapid response, did you enable the owner based policy when reproduce the issue? This issue only occurs when owner-based policy is enabled, you can also fork my reproduce repo and verify it. I confirmed conflict resolution is enabled, output of amplify cli:
Also share the network request screenshot in my side: |
Hi @sjdeak after discussing with the team, it seems that this behavior is a result of latency between the first create mutation being sent out and the record syncing back down to the client with the owner field set in the resolver. On faster network connections, this seems to happen fast enough to not be an issue, but is reproducible on slightly slower connections. We are tracking this bug on a separate ticket (#9979), and the team is working on a fix. Is there a reason why you have to update the record immediately after it was created? One way to work around this is by checking to make sure that the first mutation has been processed by the DataStore outbox prior to attempting a second mutation, or simply performing the update in a function or event separate from the creation. Deferring Update mutationsIn our docs, we provide some guidance around working with updates. For example, you can create a record, then set a copy of the record to state and update that until it's ready to be persisted to the server. Checking the Mutation OutboxThe most full-proof way to ensure that a rapid mutation will persist is to first check that the previous mutation has cleared the outbox. Here's an example of how you might do that: /**
* Watches Hub events until an outBoxStatus with isEmpty is received.
*
* NOTICE: If the outbox is *already* empty, this will not resolve.
*
* @param verbose Whether to log hub events until empty
*/
export async function waitForEmptyOutbox(verbose = false) {
return new Promise<void>(resolve => {
const { Hub } = require('@aws-amplify/core');
const hubCallback = message => {
if (verbose) console.log('hub event', message);
if (
message.payload.event === 'outboxStatus' &&
message.payload.data.isEmpty
) {
removeListener();
resolve();
}
};
const removeListener = Hub.listen('datastore', hubCallback);
});
} |
Hi Chris, I think this issue is not related to network latency, made a video demo (with voice explanation): Microsoft.Edge.mp4 |
@chrisbonifacio Would you have any updates? |
Hi @sjdeak, Happy New Year! Apologies for the delayed response. Thank you for sharing the video with more context. I don't have an update at the moment, just wanted to let you know this is on the team's radar and we are looking into a fix. We'll post any updates as they happen, thank you for your patience 🙏 Were you able to resolve the issue temporarily using some of the guidance shared before? |
Hi @chrisbonifacio Happy new year too! Looking for the good news. |
Reading through the correspondence here in more detail, I think I agree that the issue isn't resolved with the update sequencing fix that was merged earlier this week. I just reproduced your issue and I think I understand whats happening here. Because I would recommend querying for the current object just before each update to make sure your updating the latest version, similar to what you'll see in the docs. Using an older object means that in cases like this it will lose conflict resolution and your changes will be ignored preferring the existing field content. I modified the example app with the following handleClick change, moving Step 2, which resolved the issue for me. const handleClick = async () => {
const newHabit = await DataStore.save(new Habit({name: "V1", count: 1})); // Step 1
// const habitJustSaved = await DataStore.query(Habit, newHabit.id); // Step 2 <- Removed
console.log("Start to wait 5 seconds");
await new Promise(resolve => setTimeout(resolve, 5000));
console.log(await DataStore.query(Habit, newHabit.id));
console.log("Start to save modified habit");
const currentHabit = await DataStore.query(Habit, newHabit.id); // Step 2 <- Added
const modified = Habit.copyOf(currentHabit, updated => { // Step 3
updated.name = "V2";
});
console.log({modified});
await DataStore.save(modified);
}; Can you give this a try and let us know if its working as expected? Thanks, |
Hi @stocaaro thanks for the reply! Your workaround do work for me. But I think Amplify could improve this part.
|
Hello @sjdeak , You make a good point about there being an opportunity to improve Since your concern is covered in the docs and there is work in the backlog that would address the feature change your suggesting, I'm going to close this issue. Appreciate your input! Thanks, |
Thanks Aaron for your kind support, hope the backlog could be implemented in the future 🤝 |
Before opening, please confirm:
JavaScript Framework
React
Amplify APIs
DataStore
Amplify Categories
api
Environment information
Describe the bug
the modification in step 3 will not be reflected.
Expected behavior
the modification in step 3 will not be reflected.
Reproduction steps
schema.graphql
JavaScript code
In the end, step 3 will have no effect, the saved habit name is still "V1"
I observed that for step 3 there is graphql mutation request sent, however
_version
param is not included in step 3, which causes AppSync just returned original Habit data without modification applied.Code Snippet
No response
Log output
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response
The text was updated successfully, but these errors were encountered: