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

Time:01-29

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.

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.

CodePudding user response:

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

  • Related