简体   繁体   中英

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM