Manipulating data
Getting started
To get started, first import the DataStore
API:
1import { DataStore } from 'aws-amplify/datastore';
Create and update
To write data to the DataStore, pass an instance of a model to Amplify.DataStore.save()
:
1await DataStore.save(2 new Post({3 title: 'My First Post',4 rating: 10,5 status: PostStatus.INACTIVE6 })7);
The save
method creates a new record, or in the event that one already exists in the local store, it updates the record.
1// Example showing how to observe the model and keep state updated before2// performing a save. This uses the useEffect React hook, but you can3// substitute for a similar mechanism in your application lifecycle with4// other frameworks.5
6const App = () => {7 const [post, setPost] = useState();8
9 useEffect(() => {10 /**11 * This keeps `post` fresh.12 */13 const sub = DataStore.observeQuery(Post, (c) =>14 c.id.eq('5a3b284c-8afc-436a-9027-c8c32bfc8ed2')15 ).subscribe(({ items }) => {16 setPost(items[0]);17 });18
19 return () => {20 sub.unsubscribe();21 };22 }, []);23
24 /**25 * Create a new Post26 */27 async function onCreate() {28 const _post = await DataStore.save(29 new Post({30 title: `New title ${Date.now()}`,31 rating: Math.floor(Math.random() * (8 - 1) + 1),32 status: PostStatus.ACTIVE33 })34 );35
36 setPost(_post);37 }38
39 return (40 <SafeAreaView>41 <StatusBar />42 <ScrollView contentInsetAdjustmentBehavior="automatic">43 <View>44 <Text>{post?.title}</Text>45 <Button onPress={onCreate} title={'New Post'} />46 <TextInput47 disabled={!post}48 value={post?.name ?? ''}49 onChangeText={(text) => {50 /**51 * Each keypress updates the post in local React state.52 */53 setPost(54 Post.copyOf(post, (draft) => {55 draft.title = text;56 })57 );58 }}59 />60 <Button61 disabled={!post}62 title={'Save'}63 onPress={async () => {64 /**65 * This post is already up-to-date because `observeQuery` updated it.66 */67 if (!post) {68 return;69 }70 const savedPost = await DataStore.save(post);71 console.log('Post saved: ', savedPost);72 }}73 />74 </View>75 </ScrollView>76 </SafeAreaView>77 );78};
Delete
To delete an item, simply pass in an instance.
1const toDelete = await DataStore.query(Post, '1234567');2if (toDelete) {3 DataStore.delete(toDelete);4}
You can also pass predicate operators to delete multiple items. For example, the following will delete all draft posts:
1await DataStore.delete(Post, (post) => post.status.eq(PostStatus.INACTIVE));
Additionally, you can perform a conditional delete. For instance, only delete if a post is in draft status by passing in an instance of a model:
1const toDelete = await DataStore.query(Post, '123');2if (toDelete) {3 DataStore.delete(toDelete, (post) => post.status.eq(PostStatus.INACTIVE));4}
Also, to delete all items for a model you can use Predicates.ALL
:
1await DataStore.delete(Post, Predicates.ALL);
Query Data
Queries are performed against the local store. When cloud synchronization is enabled, the local store is updated in the background by the DataStore Sync Engine.
For more advanced filtering, such as matching arbitrary field values on an object, you can supply a query predicate.
Querying for all items
To query for all items, pass in the model name as the argument.
1const posts = await DataStore.query(Post);
Predicates
Predicates are filters that can be used to match items in the DataStore. When applied to a query(), they constrain the returned results. When applied to a save(), they act as a pre-requisite for updating the data. You can match against fields in your schema by using the following predicates:
For example if you wanted a list of all Post
Models that have a rating
greater than 4:
1const posts = await DataStore.query(Post, (c) => c.rating.gt(4));
Multiple conditions can also be used, like the ones defined in GraphQL Transform condition statements. For example, fetch all posts that have a rating greater than 4
and are ACTIVE
:
When using multiple conditions, you can wrap the predicates with the and
operator. For example with multiple conditions:
1const posts = await DataStore.query(Post, (c) => c.and(c => [2 c.rating.gt(4),3 c.status.eq(PostStatus.ACTIVE)4]));
Alternatively, the or
logical operator can also be used:
If you wanted this to be an or
statement you would wrap your combined predicates with c => c.or(...)
1const posts = await DataStore.query(Post, (c) =>2 c.or(c => [3 c.rating.gt(4),4 c.status.eq(PostStatus.ACTIVE)5 ]));
Pagination
Query results can also be paginated by passing in a page
number (starting at 0) and an optional limit
(defaults to 100). This will return a list of the first 100 items:
1const posts = await DataStore.query(Post, Predicates.ALL, {2 page: 0,3 limit: 1004});