1

While trying to render a functional component and trying to truncate a large paragraph on a map item using item.biography.substr(0, 20).

I have tried different syntaxes without success. Will appreciate any help. Here is my component.

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import axios from 'axios';
import $ from 'jquery';
//import "./styles.css";

function Instructor() {
  const [page, setPage] = useState(1);
  const [data, setData] = useState(['a', 'b', 'c']);
  const [isLoading, setIsLoading] = useState(true);


  const loadMoreData = () => {
    setPage(page + 1);
  };
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        'http://www.localhost/ulearn/api/getInstructors',
      );
      setData(result.data);
    };
    fetchData();
  }, []);
  return (
    <div>
      <h1> API FOR INSTRUCTOR COMPONENT </h1>
      {isLoading && <p>Wait I'm Loading comments for you</p>}

      {data.length !== 0 && (
        <button onClick={loadMoreData}>Load More Data</button>
      )}
      {data.map((item, index) => (

        <div className="col-xl-3 col-lg-4 col-md-6 col-sm-6" key={index}>
          <div className="instructor-box mx-auto text-center">
            <a href="{{ route(d.view, d.instructor_slug) }}">
              <main>
                <div className="col-md-12">
                  <h6 className="instructor-title">{item.first_name} 
                    {item.last_name}
                  `enter code here`</h6>
       <p> {item.biography.substr(0, 20)}  </p> 

                </div>
              </main>
            </a>
          </div>
        </div>
      ))}
    </div>
  );
}

if (document.getElementById('instructor')) {
  ReactDOM.render(<Instructor />, document.getElementById('instructor'));
}
4
  • Did my answer solve your question? Commented Jan 2, 2020 at 23:31
  • Yes, indeed... I tried your answer and it worked... thanks a lot Commented Jan 3, 2020 at 19:37
  • 1
    @JoseMiguelSanchez Be sure to accept wentjun's answer by clicking the check mark to the left of it. This lets others know that you no longer need help on this, and it highlights the answer for others that might come across it in the future. Welcome to Stack Overflow! Commented Jan 3, 2020 at 23:56
  • When I click to accept the correct answer I get the following message : "Thanks for the feedback! Votes cast by those with less than 15 reputation are recorded, but do not change the publicly displayed post score." Commented Jan 5, 2020 at 0:33

4 Answers 4

1

It seems like it is trying run the substring method on an undefined property? This could imply that biogarphy could be undefined.

Given that the initial state of data is ['a', 'b', 'c'], it is certain that biography is undefined while waiting for the response from fetchData() in the useEffect() hook.

In that case, you might want to do a null/undefined check and conditionally run the statement with the substr() method only if item.biography has been populated with the response from the useEffect hook

{item.biography && item.biography.substr(0, 20)}
Sign up to request clarification or add additional context in comments.

Comments

0

if string can be null you'll get the error

change this line

<p> {item.biography.substr(0, 20)}  </p>

to

 {!!item.biography && (<p>{item.biography.substr(0, 20)}</p>)}  

Comments

0

You need to add a check for biography is not undefined while using substr on it.

Also i suggest you to use .substring() as .substr is deprecated.

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import axios from 'axios';
import $ from 'jquery';
//import "./styles.css";

function Instructor() {
  const [page, setPage] = useState(1);
  const [data, setData] = useState(['a', 'b', 'c']);
  const [isLoading, setIsLoading] = useState(true);


  const loadMoreData = () => {
    setPage(page + 1);
  };
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        'http://www.localhost/ulearn/api/getInstructors',
      );
      setData(result.data);
    };
    fetchData();
  }, []);
  return (
    <div>
      <h1> API FOR INSTRUCTOR COMPONENT </h1>
      {isLoading && <p>Wait I'm Loading comments for you</p>}

      {data.length !== 0 && (
        <button onClick={loadMoreData}>Load More Data</button>
      )}
      {data.map((item, index) => (

        <div className="col-xl-3 col-lg-4 col-md-6 col-sm-6" key={index}>
          <div className="instructor-box mx-auto text-center">
            <a href="{{ route(d.view, d.instructor_slug) }}">
              <main>
                <div className="col-md-12">
                  <h6 className="instructor-title">{item.first_name} 
                    {item.last_name}
                  `enter code here`</h6>
       <p> {item.biography && item.biography.substring(0, 20)}  </p> 

                </div>
              </main>
            </a>
          </div>
        </div>
      ))}
    </div>
  );
}

if (document.getElementById('instructor')) {
  ReactDOM.render(<Instructor />, document.getElementById('instructor'));
}

1 Comment

Great this answer is perfect and solved my problem... Extremely thankful.
0

It is very possible that the content of biography is undefined, so you can add a check by conditionally rendering it to make sure it only displays the biography if biography contains a value or exists.

You can change

<p> {item.biography.substr(0, 20)} </p>

to

{item.biography && <p> {item.biography.substr(0, 20)} </p>}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.