Error using redux saga, take(patternOrChannel): argument 8 is not valid channel or a valid pattern
Asked Answered
M

2

11

I'm trying to use redux saga library to capture some actions but I'm having this error when I run the app:

index.js:2178 uncaught at rootSaga at rootSaga at projectSaga at watchFetchRequest at takeEvery Error: take(patternOrChannel): argument 8 is not valid channel or a valid pattern at take (http://localhost:3000/static/js/bundle.js:84689:9) at takeEvery (http://localhost:3000/static/js/bundle.js:85993:94) at createTaskIterator (http://localhost:3000/static/js/bundle.js:85179:17) at runForkEffect (http://localhost:3000/static/js/bundle.js:85583:24) at runEffect (http://localhost:3000/static/js/bundle.js:85468:872) at next (http://localhost:3000/static/js/bundle.js:85348:9) at proc (http://localhost:3000/static/js/bundle.js:85303:3) at runForkEffect (http://localhost:3000/static/js/bundle.js:85587:19) at runEffect (http://localhost:3000/static/js/bundle.js:85468:872) at http://localhost:3000/static/js/bundle.js:85677:14 at Array.forEach () at runAllEffect (http://localhost:3000/static/js/bundle.js:85676:10) at runEffect (http://localhost:3000/static/js/bundle.js:85468:413) at next (http://localhost:3000/static/js/bundle.js:85348:9) at proc (http://localhost:3000/static/js/bundle.js:85303:3) at runForkEffect (http://localhost:3000/static/js/bundle.js:85587:19) at runEffect (http://localhost:3000/static/js/bundle.js:85468:872) at http://localhost:3000/static/js/bundle.js:85677:14 at Array.forEach () at runAllEffect (http://localhost:3000/static/js/bundle.js:85676:10) at runEffect (http://localhost:3000/static/js/bundle.js:85468:413) at next (http://localhost:3000/static/js/bundle.js:85348:9) at proc (http://localhost:3000/static/js/bundle.js:85303:3) at runSaga (http://localhost:3000/static/js/bundle.js:85858:76) at Object../src/store/ReduxRoot.tsx (http://localhost:3000/static/js/bundle.js:95823:16) at webpack_require (http://localhost:3000/static/js/bundle.js:679:30) at fn (http://localhost:3000/static/js/bundle.js:89:20) at Object../src/index.tsx (http://localhost:3000/static/js/bundle.js:95325:75) at webpack_require (http://localhost:3000/static/js/bundle.js:679:30) at fn (http://localhost:3000/static/js/bundle.js:89:20) at Object.0 (http://localhost:3000/static/js/bundle.js:96424:18) at webpack_require (http://localhost:3000/static/js/bundle.js:679:30) at ./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js.module.exports (http://localhost:3000/static/js/bundle.js:725:37) at http://localhost:3000/static/js/bundle.js:728:10

This is the saga code:

import { all, call, fork, put, takeEvery } from 'redux-saga/effects';
import {  ActionType, Action, SearchCriteria } from '../model/types';
import { searchProjectsError, searchProjectsCompleted } from '../actions/projects';
import { API_URL } from '../../config';
// import axios from 'axios';

function callApi(method: string, url: string, path: string, data?: any) {
    return fetch(url  + path, {
      method,
      headers: {'Content-Type': 'application/json; charset=utf-8', 'Access-Control-Allow-Origin': '*'},
      body: JSON.stringify(data)
    }).then(res => res.json());
  }

// Here we use `redux-saga` to trigger actions asynchronously. `redux-saga` uses something called a
// "generator function", which you can read about here:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*

function* handleFetch(action: Action<SearchCriteria>) {
  try {
    // To call async functions, use redux-saga's `call()`.
    const res = yield call(callApi, 'get', API_URL , '/api/DocumentLoader/GetProjects/', action.payload);

    if (res.error) {
      yield put(searchProjectsError(res.error));
    } else {
      yield put(searchProjectsCompleted(res));
    }
  } catch (err) {
    if (err instanceof Error) {
      yield put(searchProjectsError(err.stack!));
    } else {
      yield put(searchProjectsError('An unknown error occured.'));
    }
  }
}

// This is our watcher function. We use `take*()` functions to watch Redux for a specific action
// type, and run our saga, for example the `handleFetch()` saga above.
function* watchFetchRequest() {
  yield takeEvery(ActionType.SEARCH_PROJECTS, handleFetch); // I think the error is here
}

// We can also use `fork()` here to split our saga into multiple watchers.
function* projectSaga() {
  yield all([fork(watchFetchRequest)]);
}

export default projectSaga;

I already tried to find an answer here in SO, but the only I could find was this post, but ActionType is been exported. I think the problem is with the parameter of handleFetch function

This is the action:

export function searchProjects(criterias: SearchCriteria): Action<SearchCriteria> {
    return {
        type: ActionType.SEARCH_PROJECTS,
        payload: criterias
    };
}

Another thing it could be is maybe I did something wrong at the time to compose the saga middleware:

const sagaMiddleware = createSagaMiddleware();

var middleware = applyMiddleware(logger, thunk, sagaMiddleware);

if (process.env.NODE_ENV === 'development') {
    middleware = composeWithDevTools(middleware);
}

// Here we use `redux-saga` to trigger actions asynchronously. `redux-saga` uses something called a
// "generator function", which you can read about here:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
export function* rootSaga() {
    yield all([fork(projectSaga)]);
  }
// running the root saga, and return the store object.
 sagaMiddleware.run(rootSaga);

I also tried removing the action parameter from handleFetch and the error is still happening

Martian answered 5/10, 2018 at 15:48 Comment(2)
I have updated my answer, just have a look!Pappose
Does this answer your question? Redux-saga get data from action returns patternOrChannel is undefinedActually
M
14

I found what was the error, the problem was the definition of ActionType enum. It was without assigning an string value for each action.

export const enum ActionType {

// Projects
SEARCH_PROJECT,
SEARCH_PROJECTS_COMPLETED,
SEARCH_PROJECTS_ERROR,

}

This fixed the problem:

export const enum ActionType {

// Projects
SEARCH_PROJECTS= '@@projects/SEARCH_PROJECTS',
SEARCH_PROJECTS_COMPLETED= '@@projects/SEARCH_PROJECTS_COMPLETED',
SEARCH_PROJECTS_ERROR= '@@projects/SEARCH_PROJECTS_ERROR',

}
Martian answered 5/10, 2018 at 18:42 Comment(1)
In general, the error is the result of not assigning the action constant to a string.Honeysuckle
P
0

The only possible error could be this:

Check whether you have imported the { ActionType } object here, from the models file where you have defined your constants.

export function searchProjects(criterias: SearchCriteria): 
    Action<SearchCriteria> {
    return {
        type: ActionType.SEARCH_PROJECTS,
        payload: criterias
    };
}
Pappose answered 5/10, 2018 at 17:9 Comment(7)
but that is not what I'm doing in the watchFetchRequest function?Martian
Sorry, thats a mistake on my part. I did not notice that part of the code. I will try to come up with the solution.Pappose
About your update, take a look the line that shows the import: import { ActionType, Action, SearchCriteria } from '../model/types';Martian
you have to import the ActionType in the file where you have the searchProjects action as well. The ActionType has to be imported in both files.Pappose
I'm doing also that, I'm using typescript, If were an error of that kind, typescript would let me knowMartian
Glad to help! Can I know what the issue was?Pappose
Take a look my answerMartian

© 2022 - 2024 — McMap. All rights reserved.