# Async Operation in RTK

## Async Operation in RTK&#x20;

RTK app that uses thunk middleware to fetch data from api and store them in the state.

{% tabs %}
{% tab title="postSlice.js" %}

```javascript
const { createSlice, createAsyncThunk } = require("@reduxjs/toolkit");
const fetch = require("node-fetch");

// initial state
const initialState = {
  loading: false,
  posts: [],
  error: "",
};

// creating async thunk
const fetchPosts = createAsyncThunk("post/fetchPosts", async () => {
  const res = await fetch(
    "https://jsonplaceholder.typicode.com/todos?_limit=5" // fetch data from api
  );

  const posts = await res.json(); // store data

  return posts;
});

// creating slice
const postSlice = createSlice({
  // Name of the slice
  name: "post",

  // Initial state for the slice
  initialState: initialState,

  // Extra reducers are used to handle actions dispatched by the `fetchPosts` thunk
  extraReducers: (builder) => {
    // When the fetchPosts action is pending, set the loading state to true and clear any previous error
    builder.addCase(fetchPosts.pending, (state, action) => {
      state.loading = true;
      state.error = "";
    });

    // When the fetchPosts action is fulfilled (successfully completed), update the state with the fetched posts
    builder.addCase(fetchPosts.fulfilled, (state, action) => {
      state.loading = false;
      state.error = "";
      state.posts = action.payload;
    });

    // When the fetchPosts action is rejected (failed), update the state with the error and clear the posts array
    builder.addCase(fetchPosts.rejected, (state, action) => {
      state.loading = false;
      state.error = action.error.message;
      state.posts = [];
    });
  },
});

// Exporting the reducer function generated by createSlice
module.exports = postSlice.reducer;

// Exporting the thunk function
module.exports.fetchPosts = fetchPosts;
```

{% endtab %}

{% tab title="store.js" %}

```javascript
const { configureStore } = require("@reduxjs/toolkit");

// importing slices
const counterReducer = require("../features/counter/counterSlice");
const keeperReducer = require("../features/keeper/keeperSlice");
const postReducer = require("../features/post/postSlice");

// importing logger from redux-logger middleware
const { default: logger } = require("redux-logger");

// configuring store (providing the reducer to redux store)
const store = configureStore({
  reducer: {
    counter: counterReducer, // Assigning the counterReducer to the "counter" slice of the store
    keeper: keeperReducer, // Assigning the keeperReducer to the "keeper" slice of the store
    post: postReducer,
  },
  // getDefaultMiddlewares() is redux's own middleware.
  // We need to return it first & concat our own middleware to use it
  middleware: (getDefaultMiddlewares) => getDefaultMiddlewares().concat(logger),
});

module.exports = store;

```

{% endtab %}

{% tab title="index.js" %}

```javascript
const store = require("./app/store");
const { counterActions } = require("./features/counter/counterSlice");
const { keeperActions } = require("./features/keeper/keeperSlice");
const { fetchPosts } = require("./features/post/postSlice");

// subscribe to state changes
store.subscribe(() => {
  // console.log(store.getState());
});

// disptach counter actions
store.dispatch(fetchPosts());

```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
We don't have to use `redux-thunk` seperately as RTK manages it automatically.
{% endhint %}
