'Changing video-background based on weather description using React

I am trying to have it so that the video background of my weather app will change based on the weather condition using React. This is my App.js

import React, { useState } from "react";
import axios from 'axios';
import Background from './Background';


function App() {
  

  const [location,setLocation] = useState('')
  const [data,setData] = useState({})
 
  const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${location}&appid=681134f49a40ffa25a43fd6bd3a2f480`

  const searchLocation = (event) => {
      if(event.key === 'Enter') {
        axios.get(apiUrl + "&units=metric")
          .then((response) => {
          setData(response.data)
          console.log(response.data)
        })
      }
  }

  return (
    <div className="app">

      <div className="search">
        <input 
        value={location}
        onChange={event => setLocation(event.target.value)}
        onKeyPress = {searchLocation}
        placeholder='Enter Location'
        type="text"/>
      </div>

      <div className="container">

        <div>
          <Background weatherDescription = {data.weather ? <p>{data.weather[0].main}</p> : null} />
        </div>   

        <div className="top">
          <div className="location">
            <p>{data.name}</p>
          </div>
          <div className="temp">
            {data.main ? <h1>{data.main.temp.toFixed()}°C</h1> : null}
          </div>
          <div className="description">
            {data.weather ? <p>{data.weather[0].main}</p> : null}
          </div>
        </div>

        {data.name != undefined && 
          <div className="bottom">
            <div className="feels">
              {data.main ? <p className="bold">{data.main.feels_like.toFixed()}°C</p> : null}
              <p>Feels Like</p>
            </div>
            <div className="humidity">
              {data.main ? <p className="bold">{data.main.humidity}%</p> : null} 
              <p>Humidity</p>
              <p></p>
            </div>
            <div className="wind">
              {data.wind ? <p className="bold">{data.wind.speed.toFixed()} KPH</p> : null} 
              <p>Wind Speed</p>
            </div>
          </div>
        }

      </div>

    </div>
  );
}

export default App;

An this is my video background component, Background.js

import React from "react";
import video1 from "./Videos/Clouds.mp4";
import video2 from "./Videos/Thunderstorm.mp4";

function Background(props) {


    const videos = [
        {
            name:"Clouds",
            background: video1

        },
        {
            name:"Thunderstorm",
            background: video2
        }
    ]


    return (
        <div>

            <video id="background" autoPlay loop muted>
                <source src = {props.weatherDescription === videos[0].name ? null : videos[0].background} type="video/mp4"/> 
            </video>

            
        </div>
    )
}



export default Background;

I have passed in the 'weatherDescription' props in App.js so that I can use it in Background.js. I have already tried If-else and I have tried ternary operator as well but it is not changing based on the description. Due to how the weatherAPI works a ternary operator has to be used to access the weather description.

I am very new to React and I am pretty sure that I am passing in the props correctly. Would you be able to see what I am doing wrong? I have tried console.logging stuff but I haven't had much luck.



Solution 1:[1]

  1. In your App.js, the props.weatherDescription you pass to Background component is JXS element(<p>{data.weather[0].main}</p>), it should be a value as string to compare, fix it like following:

<div>
  <Background weatherDescription = {data.weather ? data.weather[0].main : null} />
</div>
  1. On source tag of video, It's src have to suitable with videos array.
  2. You have to put key={videoURL} to tell React know which video to update. Below is this Background.js i think will help you:

import React from "react";
import video1 from "./Videos/Clouds.mp4";
import video2 from "./Videos/Thunderstorm.mp4";
    
    function Background(props) {
        const videos = [
            {
                name:"Clouds",
                background: video1
    
            },
            {
                name:"Thunderstorm",
                background: video2
            }
        ]
     const videoURL = videos.find(el => el.name === props.weatherDescription)?.background
        return (
        <div>
            <video id="background" key={videoURL} autoPlay loop muted>
                <source src = {videoURL} type="video/mp4"/> 
            </video>
        </div>
        )
    }
    export default Background;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 VMT