Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Redux-Saga axios api call get request with access_token does not work. Why is that?

This is a react project using axios, redux, and redux-sagas.

I am getting the following exception when trying to fetch all records from a table that are guarded. I am using JWT on my laravel backend. Login token is properly set inside local storage, I am guessing, it does not get passed properly.

Here is my git repository in case you need more details.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

TypeError: Cannot read properties of null (reading 'authService')
    at getAll (PostService.js:11:1)
    at runCallEffect (redux-saga-core.esm.js:524:1)
    at runEffect (redux-saga-core.esm.js:1204:1)
    at digestEffect (redux-saga-core.esm.js:1271:1)
    at next (redux-saga-core.esm.js:1161:1)
    at proc (redux-saga-core.esm.js:1108:1)
    at redux-saga-core.esm.js:585:1
    at immediately (redux-saga-core.esm.js:56:1)
    at runForkEffect (redux-saga-core.esm.js:584:1)
    at runEffect (redux-saga-core.esm.js:1204:1)

This is my page where I want to fetch every record from a table:

import { useEffect } from "react";
import { getAllPostsAction } from "../../store/posts/slice";
import { useSelector, useDispatch } from "react-redux";
import { makeSelectPosts } from "../../store/posts/selector";

export const PostsPage = () => {
  const posts = useSelector(makeSelectPosts);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getAllPostsAction());
  }, [dispatch]);

  console.log(posts);

  return <h1>PostsPage</h1>;
};

Saga:

import { call, put, all, fork, takeEvery } from "redux-saga/effects";
import { postService } from "../../services/PostService";
import { setAllPostsAction } from "./slice";
import { setSinglePostAction } from "./slice";

function* getPosts() {
  try {
    const response = yield call(postService.getAll);
    yield put(setAllPostsAction(response.data));
  } catch (err) {
    console.error(err);
  }
}

function* getPostsSagaWatcher() {
  yield takeEvery("posts/getAllPostsAction", getPosts);
}

...

// I forked every watcher from a file down bellow in a file

This is how I fetch everything with axios:

import { authService } from "./AuthService";
import axios from "axios";

class PostService {
  constructor() {
    this.authService = authService;
  }

  async getAll() {
    return await axios.get("http://127.0.0.1:8000/api/posts", {
      headers: this.authService.getHeaders(),
    });
  }

...

getHeaders() looks like this:

getHeaders() {
    return {
      Authorization: `Bearer ${window.localStorage.getItem("loginToken")}`,
    };
  }

I’ve tried to fetch every record in a table and setting it to component state (useState hook) on component mount which worked like a charm. So the issue is most likely the way I dispatch sagas.

>Solution :

yield call(postService.getAll);

Since you havn’t specified what the value of this should be, postService.getAll gets called using undefined for this. So when the function tries to access this.authService, it throws an error.

call has several alternate ways you can use it to specify the value of this. All of the following will work:

yield call([postService, postService.getAll])
// or
yield call([postService, 'getAll'])
// or
yield call({ context: postService, fn: postService.getAll })

See also: https://redux-saga.js.org/docs/api/#callfn-args

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading