Reputation: 3
I am using AWS Amplify Datastore in Expo / React Native to store profile information using GraphQL.
schema looks like this:
type User @model {
id: ID!
username: String
userPhone: String
createdAt: String
updatedAt: String
}
Saving it to the datastore...
let input = {
id: id,
username: username,
userPhone: userPhone,
createdAt: createdAt,
}
let myDataStore = await DataStore.save(new User({input}));
once it is saved to the Datastore it looks like this.
dataStore is User {
"_deleted": undefined,
"_lastChangedAt": undefined,
"_version": undefined,
"id": "f86d3252-7b1d-44f6-b4cd-b8a7a3a88def",
"input": Object {
"createdAt": 1593774031,
"id": "3722f35e-de54-45b2-b26e-676e2cc48160",
"userPhone": "",
"username": "One Two",
},
}
The code examples show how to retrieve this record by datastore id
DataStore.query(User, c => c.id("eq", "f86d3252-7b1d-44f6-b4cd-b8a7a3a88def"));
However i want to retrieve it by the User id ("id": "3722f35e-de54-45b2-b26e-676e2cc48160") because the user id is actually the value of the CognitoUser sub which is readily available. Querying by datastore id would require saving the datastore id in AsyncStorage, state, context, redux or whatever which is more clunky.
This does NOT work
DataStore.query(User, c => c.input.id("eq", "3722f35e-de54-45b2-b26e-676e2cc48160"));
This does NOT work
DataStore.query(User, c => c.id.id("eq", "3722f35e-de54-45b2-b26e-676e2cc48160"));
I am sure there is a simple answer but i have been googling for days and cannot figure it out.
Thank you for your help.
Upvotes: 0
Views: 1698
Reputation: 323
Adding to the previous post, you can simplify your query when retrieving a single item using the id. You just need to pass the id as the second parameter.
const user = await DataStore.query(User, "f86d3252-7b1d-44f6-b4cd-b8a7a3a88def")
Upvotes: 1
Reputation: 1382
@Mat-KH's answer was actually pointing in the right direction. Your issue is in this line (and I'm frankly surprised that this works at all, given your schema):
let myDataStore = await DataStore.save(new User({input}));
This creates a separate input
object, resulting in your data being nested inside User.input
.
Instead, you can do
// create a new User
const input = {
// id is auto-generated (see below)
username: username,
userPhone: userPhone,
createdAt: createdAt,
}
const user = await DataStore.save(new User(input));
// the above auto-generates an ID -> use that in the query below
const user = await DataStore.query(User, c => c.id("eq", "f86d3252-7b1d-44f6-b4cd-b8a7a3a88def"));
Upvotes: 1
Reputation: 76
I'd just add this as a comment, but my rank of below 50 reputation requires me to post this as an answer, so here goes:
I think you're doing things wrong, as "input" is a field inside your User object instead of only taking the parameters for the constructor. I don't know what the issue is, but I'd expect that you can't set the "id" field by yourself at all, anyway. So remove the "id" field from the input at least.
Try to get the DataStore.save() command to save a User without this "input" field in the data. Make it update/initialize the User member fields with the values instead. Then this should work:
DataStore.query(User, c => c.id("eq", "3722f35e-de54-45b2-b26e-676e2cc48160"));
as given in your original documentation.
P.S.: Maybe inline the "input" variable, so try this instead:
let myDataStore = await DataStore.save(new User({
username: "...",
userPhone: "..."
}));
Upvotes: 2