Certifications
Foundations
7. RTKQ Mutations

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

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 a ITurboPostsApiCreatePost and it should return a ITurboPost) ie. addTurboPost: builder.mutation<ITurboPost, AddTurboPostRequestData>({...})
      • path: posts/add
      • method: POST,
      • body: a stringified ITurboPostsApiCreatePost You'll need to transform the input into this type.
    • 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: AddTurboPostRequestData with an userId: 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 TurboPostForm which 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 to string[].
    • content textarea: The content of the post (string, required)
    • submit button: A submit button that calls onSubmit with 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/add route (a NextJS page).
  • It should be accessible from /turbo-posts route through a link.
  • Import useAddTurboPostMutation from @turbo-blog/api package and use it to get a callback for adding post.
  • Render the following on the page:
    • A link back to /turbo-posts-api route
    • A heading (h1) with the text Add Turbo Post (with matching page title)
    • A TurboPostForm container (created above) which shows the form and calls the callback when the form is submitted.
  • 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

  1. To verify the store setup, in the terminal, run the following command:

    yarn dev:next

    The server should start and you should be able to access the production application at localhost:3000 (opens in a new tab) in your browser.

  2. The /turbo-posts-api route must render a link to Add page and clicking a title should redirect to the /turbo-posts/add route.

  3. The /turbo-posts-api/add route must render a back link, a title, and a form.

  4. 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)