2
votes

I'm trying to get title and description JSON data from an api to display on a certain page

When a link is clicked to go too said page the title and description shows OK. On page reload I get the error: TypeError: Cannot read property 'title' of undefined.

This is where I want the data to show DataShow.tsx:

import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { fetchBook } from '../../actions';

export const DataShow: React.FC = (props: any) => {
  useEffect(() => {
    async function asyncHook() {
      const { id } = props.match.params.id;
      await props.fetchBook(id)
      return
    }
    asyncHook();
 }, []);

  // if (!props.book) {
  //   return <div>Loading...</div>
  // }

  return (
      <div>
        <h1>{props.book.title}</h1>
        <h5>{props.book.description}</h5>
      </div>
    </div>
  );
}

const mapStateToProps = (state: any, ownProps?: any) => {
  return { book: state.books[ownProps.match.params.id] }
}

export default connect(mapStateToProps, { fetchBook })(DataShow);

This is my axios function fetchBook index.ts:

import { FETCH_BOOK } from './types';
import books from '../apis/books';

export const fetchBook = (id: string) => async (dispatch: any) => {
    const response = await book.get(`/books/${id}`);
    dispatch({ type: FETCH_BOOK, payload: response.data })
}

types.ts:

export const FETCH_BOOK = 'FETCH_BOOK';

books.ts:

import axios from 'axios';

export default axios.create({
  baseURL: 'http://localhost:3002/api/v1/'
});

I've tried a couple of things like the async function inside the 'useEffect' hook which didn't work so it doesn't really make a difference as I get the same error if its there or not.

Also i've tried some conditional logic (it's commented out as you can see) but it just stays on 'loading...' as props.stream is obviously undefined.

I'm certain it has nothing to do with the api as I have multiple pages where this is not an issue.

This is the full error I get when the page reloads:

×
TypeError: Cannot read property 'title' of undefined
DataShow
src/components/books/DataShow.tsx:62
  61 |   <div>
> 62 |     <h1>{props.book.title}</h1>
     | ^  63 |     <h5>{props.book.description}</h5>
  64 |   </div>
  65 | </div>

This error is displayed is the console when the link is clicked and you go to the requested page even though the data (title and description) is showing correctly:

GET http://localhost:3002/api/v1/books/undefined 404 (Not Found) xhr.js:178 

Thanks

2
actual problem us props.book is undefined, uncomment below lines and check, // if (!props.book) { // return <div>Loading...</div> // } make sure that props.book having some data, then it will works.rohit
you need to add a loader to your component. It's just a boolean. make it true just before calling API and then after response make it false. Use that boolean to show and hide the top divSachin
as i said in my post if that is uncommented then the page just displays "Loading..."Max

2 Answers

0
votes

props.book?.title
props.boon?.description

your Return method of react running before coming props so use this to hold while props came or you can also use old method props.book&&props.book.title

0
votes

You can check for book object.

{props && Object.keys(props.book).length>0 ? 
  <div>
    <h1>{props.book.title}</h1>
    <h5>{props.book.description}</h5>
  </div>:
  <div>
    <p>No book found..</p> 
  </div>
}