0

I am working on my Portfolio, and currently i am mapping over an array to create a list of projects that contain multiple images as a Slider(Swiper) Component.

Now what i need would be the possibility to also include videos instead of an image. So i think i might need something that checks if the passed file is an image or a video and then selects the fitting html tag ( / ) Is there a simple way to achieve this?

My Code sample (reduced to relevant parts):

Mapping over a Project Component to generate projects:

{allData.map((project) => (
  <Project id={project.id} text={project.title} vids={project.videos} imgs={project.images} description={project.info} />
))}

Passing the data to the Project Component:

const Project = ({ text, vids, imgs, description }) => {
                        {imgs.map(e => (
                            <SwiperSlide>
                                <div className="image-container">
                                    <img className="image-center" src={e} />
                                    
                                </div>
                            </SwiperSlide>
                        ))}
                        
                        {vids.map(video => (
                            <SwiperSlide>
                                <video src={video} />
                            </SwiperSlide>
                        ))}

What the array looks like:

import img1 from './img/1.jpg';
import img2 from './img/2.jpg';
import img3 from './img/3.jpg';
import video1 from './video/1.mp4';

const allData = [
    {
        id:1,
        images: [img1, img2, img3]
        title: 'Example-title',
    },
    {
        id:2,
        images: [img3]
        videos: [video1]
        title: 'Example-title',
    }
export default allData 

Can someone please help me out with this?

jamesrogers
  • 67
  • 10
  • 2
    The list of file types that are images and the file types of videos have zero overlap, I believe - the one semi-overlap (the animated gif) works fine as an image... So just a regex or something would work - like function isImage(imageName) { return /\.(gif|png|webp|jpg|jpeg)$/i.test(imageName); } might do it – Count Spatula Jan 28 '22 at 22:23
  • I don't really understand the issue at hand, because by using `imgs={project.images}` in your JSX template, you are always exclusively passing in images to the `imgs` prop... unless you have not shared the other parts of your code that passes in videos as well? – Terry Jan 28 '22 at 22:50
  • hi, i've edited the code above, so that also video would be passed, but i dont know how to map two arrays at the same time? – jamesrogers Jan 28 '22 at 23:00
  • Is there an order? Like, should all images come first then videos, or...? – Terry Jan 28 '22 at 23:00
  • Not necessarily, but good question.. at the moment im just putting the imgs in the array how i want them to be in order. but if so, then id like the videos before images – jamesrogers Jan 28 '22 at 23:04
  • 1
    Why not call `imgs.map(...)` as you are currently doing, followed by `vids.map(...)`? Each of those would generate the corresponding correct HTML tags (`` or ` – kmoser Jan 28 '22 at 23:07
  • Thank you so much! Thats it! So simple actually. – jamesrogers Jan 29 '22 at 11:43

2 Answers2

1

Try This:

 const isImage = ['.gif','.jpg','.jpeg','.png']; //you can add more
 const   isVideo =['.mpg', '.mp2', '.mpeg', '.mpe', '.mpv', '.mp4'] // you can add more extention
    
//merge image and video in single array

const Project = ({ text, files, description }) => {
                        {files.map(e => (
                            <SwiperSlide>
                                <div className="image-container">
                                   { isImage?.includes(e) && <img className="image-center" src={e} />  }
                                      {isVideo?.includes(e) && <video src={e} />  }
                                </div>
                            </SwiperSlide>
                        ))}
}

Thanks.

  • Do you think a similar approach could work for this issue? https://stackoverflow.com/questions/75842234/add-img-video-specified-in-data-src-to-another-container-on-hover – user1406440 Mar 26 '23 at 08:28
0

const videoExtensions = ['.mpg', '.mp2', '.mpeg', '.mpe', '.mpv', '.mp4'] //you can add more extensions
const imageExtensions = ['.gif', '.jpg', '.jpeg', '.png'] // you can add more extensions

let status

const isImage = (v) => {
  imageExtensions.map((e) => {
    status = v.includes(e);
  })
  return status
};
const isVideo = (v) => {
  videoExtensions.map((e) => {
    status = v.includes(e);
  })

  return status
};

// To use
console.log(isImage("https://gist-cdn.azureedge.net/videos/20233/94044102-46bf-4a15-a674-48e63fdac6bf.mp4"))

console.log(isVideo("https://gist-cdn.azureedge.net/videos/20233/94044102-46bf-4a15-a674-48e63fdac6bf.mp4"))
  • Checking by extension is a good idea, however your `status` result of each function is going to get overwritten by the `v.includes(e)` for each item in the arrays, ending with the last item. So if you change your two sample URLs to end in `.mpg` or `.gif` for instance, both functions will return false. – kwill Mar 10 '23 at 16:24