Datastore - Observe query results in real-time with @hasOne relation doesn't add nested data after first sync
sebboe opened this issue · 11 comments
Before opening, please confirm:
- I have installed the latest version of the Amplify CLI (see above), and confirmed that the issue still persists.
- I have searched for duplicate or closed issues.
- I have read the guide for submitting bug reports.
- I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
- I have removed any sensitive information from my code snippets and submission.
How did you install the Amplify CLI?
npm
If applicable, what version of Node.js are you using?
No response
Amplify CLI Version
7.6.22
What operating system are you using?
Mac
Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.
No manual changes made
Amplify Categories
api
Amplify Commands
Not applicable
Describe the bug
I'm facing an issue while observing objects with "@hasone" relationship. When adding a new object, the observer returns only the main object, without the relation field. After one refresh/moving to another component and coming back, the nested object appears as part of the main object.
observeQuery(...) returns an initial data set, similar to query(...), and also automatically subscribes to subsequent changes to the query.
Expected behavior
I would like to directly return the nested object.
Reproduction steps
- Link two models with "@hasone"
- Add object with relation
- Observe objects:
this.flightList = DataStore.observeQuery(Flight).subscribe(snapshot => {
const { items, isSynced } = snapshot;
console.log(`[Snapshot] item count: ${items.length}, isSynced: ${isSynced}`);
console.log(items);
this.flights = items;
});
GraphQL schema(s)
# Put schemas below this line
type Flight @model {
id: ID!
pilot: String!
airplane: Aircraft @hasOne(fields: ["airplaneId"])
airplaneId: ID
}
type Aircraft @model {
id: ID!
registration: String!
category: String
lastIndex: String
specs: AircraftSpecs
}
type AircraftSpecs {
passenger:Boolean
fuel:String
}
Log output
# Object returned right after saving it:
{
"id": "5a91ab15-0866-4919-9703-3083018cdeab",
"pilot": "Sébastien",
"airplaneId": "3e154d19-af70-47d2-9d66-829fce65b93a",
"_version": 1,
"_lastChangedAt": 1646679807385,
"_deleted": null
}
# Object returned after refresh
{
"id": "5a91ab15-0866-4919-9703-3083018cdeab",
"pilot": "Sébastien",
"airplaneId": "3e154d19-af70-47d2-9d66-829fce65b93a",
"_version": 1,
"_lastChangedAt": 1646679807385,
"_deleted": null,
"airplane": {
"id": "3e154d19-af70-47d2-9d66-829fce65b93a",
"registration": "AV-ION",
"category": "Airplane",
"lastIndex": "22299:99",
"createdAt": "2022-03-06T23:30:51.363Z",
"updatedAt": "2022-03-07T19:03:27.671Z",
"specs": {
"passenger": true,
"fuel": "AVGAS"
},
"_version": 8,
"_lastChangedAt": 1646679807692,
"_deleted": null
}
}
Additional information
No response
Hey @sebboe
As a workaround, instead of using data returned by the subscription, I call a classic DataStore.query when new data are emitted.
this.flightList = DataStore.observeQuery(Flight).subscribe(snapshot => {
//const { items, isSynced } = snapshot;
//console.log(`[Snapshot] item count: ${items.length}, isSynced: ${isSynced}`);
this.refreshData().then(flights => {
this.flights = flights;
console.log(this.flights);
})
});
}
async refreshData(){
this.flights = await DataStore.query(Flight);
return this.flights
}
I also see this issue and the same problem arises after updating the model. The re-query workaround addresses both issues.
I am also have this issue, I'll try the re-query workaround.
@sebboe This should be fixed. Are you still seeing this problem on the latest version of amplify?
I am still not receiving nested objects from the observe part of observeQuery and my datastore version is 3.12.6 (most up to date)
One thing about updating relationships as being different from adding a new one. In the above example, if postID is null then updating the Comments document only requires setting postID. If postID is already pointing to post "A", then updating just postID to the ID of post "B" fails. Update (and delete - set posID=null) of an existing relationship requires also setting post to the "B" post model.
Why is setting the model reference field required? post is a calculated field.
I have also noticed that one can set postID to anything if postID was null previously. If postID is a value that is not the ID of a Post document, then no error is generated on the update. querying/observing will obviously not return a Post model in the post field in this case.
I'm not able to reproduce this. It may have been incidentally fixed with the lazy loading change. Please comment if you are still experiencing this issue.