API Integration

Doot react having fake-backend setup already. you will find all files related to API integrations in the src/API folder.

  • src/apiCore.ts file contains axios setup to call server API(s) including get, put, post, patch, delete, etc methods, interceptors & token set methods.

  • src/index.ts file contain all module's API call functions which are exported from each module's individual .ts file, E.g. contacts.ts, bookmarks.ts etc.

  • src/urls.ts file contain all module's API's url.

Note : we have added a Fake backend setup just for user interactions, but if you are working with the real API integration, then there is no need of fake backend as well as the fakeBackend file located in src/helpers/fakeBackend.ts, so you can delete it and also remove the code related to fakeBackend from app.tsx file. you just need to update API's url of the related module from src/apiCore/urls file, that's it!
How to Integrate custom API?

Please follow the below steps to make the custom API working.

  1. let's assume that our API's url is "..baseurl/user-profile-details/{userId}". so implement it, first we have to add this url in src/apiCore/urls.ts file, so open the file and add the following code.
    ...
    export const USER_PROFILE_DETAILS = "/user-profile-details";
  2. if this is a new module of your app, then create a new .ts file in src/apiCore/ folder named userProfile.ts and write following code in it.
    import { APIClient } from "./apiCore";
    import * as url from "./urls";
    
    const API = new APIClient();
                                          
    const getUserDetails = (userId : number | string) => {
      return API.get(`${url.USER_PROFILE_DETAILS}/${userId}`);
    };
    
    export { getUserDetails };
    
    do not forget to export newly created file's content (userProfile.ts) in index.ts file, let's do this.
    ...
    export * from "./userProfile";
    
  3. After the above setup, We will do redux action's setup. Please check How To Create Actions & Saga first.

    Create a folder named with your module in src/redux folder i.e. demo module then it should be src/redux/demo then create actions.ts, saga.ts, reducer.ts & actionTypes.ts files and follow the pattern of other modules which are added in this template. Also do not forget to export it in main files (actions.ts, reducers.ts and sagas.ts ) of src/redux folder.

  4. Add your action name in the actionTypes.ts file. E.g.
    export enum UsersActionTypes {
      GET_USER_PROFILE_DETAILS = "@@users/GET_USER_PROFILE_DETAILS",
    }
    
    export enum UsersState {
      userDetails : object
    }
    
  5. Create the action in the action.ts file. And make sure you pass the same action type as a type parameter which you added in actionTypes.ts file.
    import { UsersActionTypes } from "./types";
    
    // common success
    export const usersAPIResponseSuccess = (actionType: string, data: any) => ({
      type: UsersActionTypes.API_RESPONSE_SUCCESS,
      payload: { actionType, data },
    });
    
    // common error
    export const usersAPIResponseError = (actionType: string, error: string) => ({
      type: UsersActionTypes.API_RESPONSE_ERROR,
      payload: { actionType, error },
    });
    
    export const getUserDetails = (userId : string | number) => {
      return {
        type: UsersActionTypes.GET_USER_PROFILE_DETAILS,
        payload: userId
      }
    }
    
  6. Add your action to the reducer.ts as well. Here, we can have either success or error response from the API. so we will manage this by API_RESPONSE_SUCCESS & API_RESPONSE_ERROR actions.
    import { UsersActionTypes, UsersState } from "./types"
            
    const INIT_STATE : UsersState = {
      userDetails: {},
    }
            
    const User = (state = INIT_STATE, action: any) => {
      switch (action.type) {
        case UsersActionTypes.API_RESPONSE_SUCCESS:
          switch (action.payload.actionType) {
            case UsersActionTypes.GET_USER_PROFILE_DETAILS:
              return {
                ...state,
                userDetails: action.payload.data,
                isDetailsFetched: true,
                getDetailsLoading: false,
              };
            default:
              return { ...state };
          }
    
        case UsersActionTypes.API_RESPONSE_ERROR:
          switch (action.payload.actionType) {
            case UsersActionTypes.GET_USER_PROFILE_DETAILS:
              return {
                ...state,
                error : action.payload.error,
                isDetailsFetched: false,
                getDetailsLoading: false,
              };
    
            default:
              return { ...state };
          }
    
        case UsersActionTypes.GET_USER_PROFILE_DETAILS: {
          return {
            ...state,
            getDetailsLoading: true,
            isDetailsFetched: false,
          };
        }
                
        default:
          return { ...state }
        }
    }
            
    export default User
    
  7. Now, create saga.ts file and Add saga funtion & watchers for the action.
    import { takeEvery, fork, put, all, call } from "redux-saga/effects";
    
    // Login Redux States
    import { UsersActionTypes } from "./types";
    import { usersAPIResponseSuccess, usersAPIResponseError } from "./actions";
                                          
    import { getUserDetails as getUserDetailsAPI } from "../../API/index";
    
    function* getUserDetails({ payload: userId }: any) {
      try {
        const response: Promise = yield call(getUserDetails, userId);
        yield put(usersAPIResponseSuccess(UsersActionTypes.GET_USER_PROFILE_DETAILS, response));
      } catch (error: any) {
        yield put(usersAPIResponseError(UsersActionTypes.GET_USER_PROFILE_DETAILS, error));
      }
    }
                                          
    export function* watchGetUserDetails() {
      yield takeEvery(UsersActionTypes.GET_USER_PROFILE_DETAILS, getUserDetails);
    }
                                          
    function* usersSaga() {
      yield all([fork(watchGetUserDetails)]);
    }
                                          
    export default usersSaga;
  8. After redux & saga's setup, you just need to call the action from your component. E.g.
    import React from 'react';
    import React, { useEffect, useState } from "react";
    
    //redux
    import { useSelector, useDispatch } from "react-redux";
    
    // actions
    import { getUserDetails } from "../../../redux.actions";
    
    interface IndexProps {}
                                        
    const Index = (props: IndexProps) => {
      const dispatch = useDispatch();
      const { userDetails } = useSelector((state: any) => ({
        userDetails: state.User.userDetails,
      }));
    
      /*
      get user derails, here, userId = 2
      */
      useEffect(() => {
        dispatch(getUserDetails(2))
      },[dispatch]);
    
      // your API's response data will be in userDetails variable.
      console.log(userDetails);
    
      return (
        <div>
        </div>
      );
    }
                                        
    export default Index;
© Themesbrand.
Crafted with by Themesbrand