0

In a React project, I have JSON data as follows

const data = [
  { id: '123abc', comment: 'How are you?' },
  { id: '234abc', comment: 'https://flower.jpg' },
  { id: '123xyz', comment: 'Whatsupp?' },
  { id: '335sde', comment: 'https://galaxy.png' },
];

I'am trying as under

<div>
{/* For images */}
<img src={data.comment} height="50px"/>

{/* For text */}
<Typography variant="caption">
   {data.comment}
</Typography>
</div>

As seen above some comments are text whereas some are images. So, how to render it? Any appropriate solution highly appreciated

5
  • what's problem? Commented Feb 15, 2021 at 4:09
  • you add id for determine text or image in object json Commented Feb 15, 2021 at 4:10
  • Yes but what conditions need to apply for rendering text or image? Commented Feb 15, 2021 at 4:20
  • Is the issue that you want to show images if a string is a url, and render text otherwise? If so, you can use regex like the one here (stackoverflow.com/questions/2838404/…) to check if a string is a valid url, and to render it as text otherwise. Commented Feb 15, 2021 at 4:29
  • conditional-rendering Commented Feb 15, 2021 at 6:00

2 Answers 2

3

create function for check URL and use conditional rendering.

validateUrl = (string) => {
    var res = string.match(
      /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g
    );
    return res !== null;
  };
  render() {
    return (
      <div>
        {this.validateUrl(data.comment) ? (
          <img src={"data.comment} height="50px" />
        ) : (
          <Typography variant="caption">{data.comment}</Typography>
        )}
        
        {/* // for comment:"How are you?" it returns false and it renders text and
        for comment:"https://galaxy.png" it returns true and it renders image */}
      </div>
    );
  }
Sign up to request clarification or add additional context in comments.

1 Comment

fwiw, I would advise to create the desired function outside of render method. otherwise each rerender validateUrl is recreated.
0

This should work:

const data = [
  { id: '123abc', comment: 'How are you?' },
  { id: '234abc', comment: 'https://flower.jpg' },
  { id: '123xyz', comment: 'Whatsupp?' },
  { id: '335sde', comment: 'https://galaxy.png' },
];

const validateUrl = (string) => {
  const result = string.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g)
  return result !== null;
}

const renderImage = (link) => (<img src={link} height="50px"/>)
const renderTypography = (comment) => (
  <Typography variant="caption">
    {comment}
  </Typography>
);

render () {
  return data.map(row => (
    <div>
      validateUrl(row.comment) ? renderImage(row.comment) : renderTypography(row.comment)
    </div>
  ))

}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.