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 })