0
votes

*This is a React-Redux tutorial, so please no other solutions :)

Desired behavior: Pass props of parent component to the PostDetail component from state controlled by redux

Current output:

(1) 204 Result:

http://localhost:3001/react/8xf0y6ziyjabvozdd253nd
Request Method: OPTIONS
**strong text**Status Code: 204 No Content

(2) Consoled Errors:

GET http://localhost:3001/react/8xf0y6ziyjabvozdd253nd 404 (Not Found)
    :3000/react/8xf0y6ziyjabvozdd253nd:1 

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

Inside my app (root.js) file I have the PostDetail component I want to route to like this:

    import React, { Component } from 'react';
    import { Route } from 'react-router-dom'
    import Categories from './Categories'
    import ListPosts from './ListPosts'
    import Header from './Header'
    import PostDetail from './PostDetail'

    class App extends Component {
      render() {
        return (
          <div>
            <Header />
            <Categories />
            <ListPosts />
            <Route exact path="/:category/:id" component={PostDetail}/>
         </div>

Then in the PostDetail nested component (inside the ListPosts component) I have a function inside a material-ui flatbutton, (important sidenote: The PostDetail component does have a console.log statement that is being called, but the props.post is undefined):

    selectPost = (selectedCategory, selectedPost) => {
      console.log('selectedCategory', selectedCategory, selectedPost)
      this.props.getSpecificPost(selectedCategory, selectedPost);
    }
   return (
    <CardActions>
        <FlatButton
          label="See Thread"
          // href={`/${post.category}/${post.id}`}
          containerElement={<Link to={`/${post.category}/${post.id}`} post={this.props.post} />}
          onClick={() => this.selectPost(post.category, post.id)}
        />
      )

In this same component are my mapStateToProps and mapDispatchToProps:

   const mapStateToProps = state => ({
     posts: state.postsReducer.posts,
     loading: state.postsReducer.loading,
     error: state.postsReducer.error,
     selectedCategory: state.categoriesReducer.selectedCategory,
     selectedPost: state.postsReducer.selectedPost,
   });

  function mapDispatchToProps (dispatch) {
    return {
     getSpecificPost: (selectedCategory, selectedPost) => 
         dispatch(getSpecificPost(selectedCategory, selectedPost)),
     fetchPosts: (selectedCategory) => dispatch(fetchPosts(selectedCategory))
    }
   }

 export default withRouter(connect(
   mapStateToProps,
   mapDispatchToProps
  )(PostPreview))

I am using a redux-thunk action call that is calling to my api:

   export function getSpecificPost(selectedCategory, selectedPost) {
     console.log('getSpecificPost', selectedPost)
     return dispatch => {
      dispatch(beginFetchPosts());
      return fetch(selectedPost ? `${api}/${selectedCategory}/${selectedPost}` 
          : null, { headers })
      .then(
       res => res.json(),
       error => console.log('An error occured at  getSpecificPost', error)
       )
       .then(json => {
         dispatch(selectPostSuccess(json));
         return json
         })
        }
       }

And a reducer:

    const initialState = {
     posts: [],
     categories: [],
     loading: false,
     error: null,
     selectedCategory: 'all',
     selectedPost: [],
     };

   export function postsReducer(state = readableInitialState, action) {
      switch(action.type) {
        case C.SELECTED_POST:
          return {
          ...state,
          loading: false,
          selectedPost: action.payload.selectedPost
         };

...And yes I finish the switch statement with a default statement and no syntax issues as far as a I know)

2

2 Answers

1
votes

Whenever I see the error

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

I get flashbacks to CORS issues that I had to tough out when setting up a project the first time and hitting a remote server for dev.

Could you provide your network response when going to this page from chrome dev tools? There should be no < at the start of a JSON so I'm thinking you don't have a react router issue but some sort of server config issue.

1
votes

The problem is that you did not mention the method, whether it is GET, PUT and that is why the server is considering OPTIONS. You can use fetch call in a different way.

export function getSpecificPost(selectedCategory, selectedPost){
  return (dispatch) => {
    const baseURL = selectedPost ? `${api}/${selectedCategory}/${selectedPost}` : null 
    fetch(baseURL, {
      method: 'GET',
      headers: {
        'content-type': 'application/json'
      },
      body: JSON.stringify(`${headers}`)
    })
    .then(json => {
      dispatch(selectPostSuccess(json))
    })
  } 
}

You can also send data to the reducer instead of json by following code snippet.

export function getSpecificPost(selectedCategory, selectedPost){
  return (dispatch) => {
    const baseURL = selectedPost ? `${api}/${selectedCategory}/${selectedPost}` : null 
    fetch(baseURL, {
      method: 'GET',
      headers: {
        'content-type': 'application/json'
      },
      body: JSON.stringify(`${headers}`)
    })
    .then(json => response.json())
    .then(data => {
      dispatch(selectPostSuccess(data))
    })
  } 
}

I hope this could help you.