Kevin Su
Kevin Su

Reputation: 1

How to create React component that can render Img or Video depending on API data it recieves

I am currently learning and practicing React.

I am trying to achieve a react web app that allows you to display and scroll through Nasa's picture of the day based on what date you choose. here's the api: api.nasa.gov/

the project is simple BUT. sometimes the url that the api returns, leads to an img and sometimes a youtube video. for example:

https://apod.nasa.gov/apod/image/1708/PerseidsTurkey_Tezel_960.jpg

or

https://www.youtube.com/embed/Zy9jIikX62o?rel=0

I have managed to display both cases using an iframe. I know this is not ideal for the imgs because I cannot format it properly with css and it just looks bad with the scroll bars, sizing etc..but won't display the video..

this is what the react component looks like (using bootstrap)

detail.js

import React, { Component } from 'react';

export default class Detail extends Component {
  render() {
    return (
      <div className="video-detail col-md-12">
        <div className="embed-responsive embed-responsive-16by9">
            <iframe className="embed-responsive-item" src={this.props.url}>
            </iframe>    
        </div>  
      </div>
    );
  }
}

I would like to images also to display responsively, centered and original aspect ratio but also still have the videos display properly as they are.

I have tried putting an additional <img> underneath the <iframe> but that just renders the image twice. Is there a way to render an <img> or <iframe> conditionally?

I am wondering what strategy should I try next? Any ideas?

Thanks!

Upvotes: 0

Views: 2845

Answers (2)

William A. Ferguson
William A. Ferguson

Reputation: 29

Yon don't even have to use a split().pop(). Just scan the API return for a media type (much simpler, really):

const Photo = props => (
    <div>
      <h3 className="m-5 text-center">{props.photo.title}</h3>
      {props.photo.media_type === "image" ? ( 
      <img className="rounded mx-auto d-block" src={props.photo.url} alt={props.photo.title} />
      ) : (
          <iframe
            title="space-video"
            src={props.photo.url}
            frameBorder="0"
            gesture="media"
            allow="encrypted-media"
            allowFullScreen
            className="mx-auto d-block"
            />        
        )}
      <p className="col-md-8 offset-md-2 mt-5 pb-5">{props.photo.explanation}</p>
    </div>

Upvotes: 2

Amir Ghezelbash
Amir Ghezelbash

Reputation: 2415

you should use conditional rendering

const isImage = this.props.url.split().pop() === 'jpg';
return (
   {
     isImage ? <img src={this.props.url} />
     : <iframe className="embed-responsive-item" src={this.props.url}>
        </iframe> 
   }
)

or

const isImage = this.props.url.split().pop() === 'jpg';
return (
   {
     isImage && <img src={this.props.url} />
   }
   { 
     !isImage && <iframe className="embed-responsive-item" src={this.props.url}>
        </iframe> 
   }
)

Upvotes: 2

Related Questions