Song Turbo Developer Certification - Foundations
Part 7: RTK Query - Mutations
This part deals with setting up and using RTK Query Mutations. Mutations are used to send data updates to the API and apply the changes to the local cache. Mutations can also invalidate cached data and force re-fetches.
We also get to know how to use React Hook Form for managing forms and validation.
Concepts
- Queries and Mutations
Reading material
- RTK Query (opens in a new tab)
- with TypeScript (opens in a new tab)
- Mutations (opens in a new tab)
- React Hook Form (opens in a new tab)
Tasks
In this task, the turboPostsApiSlice that you created before will be extended.
1. Define new types
First we need to define types for the data coming from the form and going to and from the API
- The data coming from the form (
AddTurboPostRequestData) - The data to be sent to the API (
ITurboPostsApiCreatePost) - The data coming from the API as result of the post (
ITurboPostsApiCreatePostResult)
Refer to references
2. Inject addTurboPost endpoint
- Add the following endpoint to
extendedTurboPostsApiSlice:addTurboPost: Add posts to API service (the input of the endpoint is aITurboPostsApiCreatePostand it should return aITurboPost) ie.addTurboPost: builder.mutation<ITurboPost, AddTurboPostRequestData>({...})- path:
posts/add - method:
POST, - body: a stringified
ITurboPostsApiCreatePostYou'll need to transform the input into this type.
- path:
- Include transformer function to transform the API response into a
ITurboPost
- Export the generated hooks from
extendedTurboPostsApiSlice:useAddTurboPostMutation
Note: Docs for the API service used (opens in a new tab).
Since this is a POST request, there are 2 things that need to be done:
- Add following headers to the request:
'Content-Type': 'application/json'- Add the body of the request:
AddTurboPostRequestDatawith anuserId: 1. The API needs an user Id but we don't receive one from the add-post-form (out-of-scope).
3 Create a TurboPostForm container (and ui components) for adding post
Containers are good for isolating logic and keeping the UI clean. Allways make sure that you split your components into a UI part and a logic part.
For handling form data and valiation use React Hook Form (https://react-hook-form.com/get-started (opens in a new tab))
-
Create a new container
TurboPostFormwhich will be used to add posts. -
It should receive following props:
isLoading: If form is in loading state (boolean, optional)error: If there is error when calling the mutation (string, optional)onSubmit: A callback function that should be called from TurboPostForm when the form is submitted. The function should have the form data as a parameter. This function does the actual mutation api call to save the post.
-
It should render a form with the following fields:
heading input: The title of the post (string, required)tags input: The tags of the post (string, comma-separated, optional). Later transformed tostring[].content textarea: The content of the post (string, required)submit button: A submit button that callsonSubmitwith the form data. The button is disabled when the form is loading.error message: If there is error with submission. Hide if no error.
Note that the rendering should be done using UI components. So you need to create at least two UI components here (each with stories). A UI component called `TextInput' which is a form input field, and a 'TurboPostForm' UI component.
Exactly which UI components you create is not the most important part. Only that there is no styling in containers, and no logic in ui components.
The UI library should not have a dependency on react-hook-form. Or any other
library that manages state, validation or logic. UI components only task
should be to present the data given to them in the props
- The form should remove the error message when the user submits the form again.
- The form should clear all inputs if the form is submitted successfully.
4. Create add route
- Create a new
/turbo-posts-api/addroute (a NextJS page). - It should be accessible from
/turbo-postsroute through a link. - Import
useAddTurboPostMutationfrom@turbo-blog/apipackage and use it to get a callback for adding post. - Render the following on the page:
- A link back to
/turbo-posts-apiroute - A heading (h1) with the text
Add Turbo Post(with matching page title) - A
TurboPostFormcontainer (created above) which shows the form and calls the callback when the form is submitted.
- A link back to
- When the form is successfully submitted and a new post is created/returned, show the new post in an alert or notification message. And clear the form.
Note: Normally, after a successful submission the user should be redirected to the
/turbo-posts-api/[newPost.id]route, but since the API is a dummy, we will not do that.
5. Commit your changes
Evaluation
-
To verify the store setup, in the terminal, run the following command:
yarn dev:nextThe server should start and you should be able to access the production application at localhost:3000 (opens in a new tab) in your browser.
-
The
/turbo-posts-apiroute must render a link to Add page and clicking a title should redirect to the/turbo-posts/addroute. -
The
/turbo-posts-api/addroute must render a back link, a title, and a form. -
Submitting the form should show the success result in an alert/notice. If an error occurs, it should show the error inline with the form.
Bonus 1: Make sure the form is accessible and usable with just keyboard.
Bonus 2: After successful creation of post manually update the RTK Query cache. So that when you go back to the list, your newly created post is listed. See https://redux-toolkit.js.org/rtk-query/usage/manual-cache-updates (opens in a new tab)