0
votes

Using "react-router-dom": "^4.1.2", "react-router-redux": "^5.0.0-alpha.6" I get as per title "Uncaught TypeError: Cannot read property 'type' of undefined React Router Redux" in console.log() the moment after the redirect is done. Screenshots show it's not a problem with the action observable containing the payload data. Payload contains form data (values) and history object. I managed to send them and then capture them by means of a recursive function that uses mergeMap instead of ES6 map since I am dealing with Observables. link to the repo

enter image description here

    import * as ActionTypes from "../ActionTypes";
    import { createPostFulfilled, fetchPosts, fetchPostsFulfilled, fetchPostsWithIdFulfilled, changeRoute } from "../actions";
    import {store, history} from "../configureStore";
    import { Observable } from "rxjs/Observable";
    import "rxjs/add/observable/combineLatest";
    import "rxjs/add/operator/debounceTime";
    import { concat as concat$ } from "rxjs/observable/concat";
    import { from as from$ } from "rxjs/observable/from";
    import { of as of$ } from "rxjs/observable/of";
    import "rxjs/add/operator/map";
    import "rxjs/add/operator/mergeMap";
    import "rxjs/add/operator/startWith";
    import "rxjs/add/operator/filter";
    import "rxjs/add/operator/switchMap";
    import "rxjs/add/operator/concatMap";
    import "rxjs/add/operator/catch";
    import "rxjs/add/observable/dom/ajax";
    import {push} from "react-router-redux";
    const ROOT_URL = "http://reduxblog.herokuapp.com/api";
    const API_KEY = "key=davide123";

    export  const fetchPostsEpic = (action$) => {

        return action$.filter((action$)=> action$.type === ActionTypes.FETCH_POSTS)
            .mergeMap(action$ => {
              return  Observable.ajax.getJSON(`${ROOT_URL}/posts/?${API_KEY}`)
                    .map(response => fetchPostsFulfilled(response), (err) => {console.log(err);});
            });
    };

    export const fetchPostsWithIdEpic = (action$) => {
        return action$.filter((action$)=> action$.type === ActionTypes.FETCH_POSTS_WITH_ID)
        .mergeMap(action$ => {
          return  Observable.ajax.getJSON(`${ROOT_URL}/posts/?${action$.payload}&${API_KEY}`)
                .map(response => fetchPostsWithIdFulfilled(response), (err) => {console.log(err);});
        });
    };

    export  const createPostEpic = (action$) => {
        const actionVectorizer = ((action$) => {
            if (action$)
            return action$.isArray() ?   [].concat(...action$.mergeMap(x => actionVectorizer(x))) : action$;
        })();
        return action$.filter((action$)=> action$.type === ActionTypes.CREATE_POST)
            .mergeMap(action$ => {
                    console.log("action$ is...");
                    console.log(action$);
                    let { values, history } = action$.payload;
                    return   Observable.ajax.post(`${ROOT_URL}/posts/?${API_KEY}`, values)
                            .map(
                                (data) => {
                                    if (data.status === 201) {
                                        console.log("Success status", data.status);
                                        history.push("/");
                                        // return createPostFulfilled(data.status);
                                    }
                                    else {console.log("Server error is", data.status);}
                                },
                                (err) => {console.log(err);}
                            );
            });
    };
1

1 Answers

1
votes

Inside createPostEpic you map the result of the ajax call to nothing (undefined) because your action creator invocation and return is comment out, so your epic ends up emitting the value undefined:

history.push("/");
// return createPostFulfilled(data.status);

That undefined value will be dispatched and redux-observable first passes it along to either the next middleware (or the root reducer). In your case, react-router-redux middleware is next, so it receives it.

However, react-router-redux expects only true actions, so it errors because it tries to look up action.type but action is undefined.


I think you'd really enjoy learning more about Chrome's powerful debugging tools, like its ability to Pause on Uncaught Exceptions (or even Caught ones). Using it I was able to find the cause nearly immediately. A very rewarding skill that has made my life so much easier.