I'm trying to make a FAQ of sorts, right now I have it as a search bar but I'm having a hard time sending a value that I want the videos to populate with. I want the user to have the option to click on the button, and that specific button have the data of "How to find a queen" and send that automaitcally to the iframe player. Any pointers on how to achieve this? As I have it right now, my handleSubmit populates the search bar.
SearchBar.jsx
import React, { useState } from 'react';
import "./SearchBar.css";
const SearchBar = (props) => {
const [searchRequest, setSearchRequest] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
props.getSearchResults(searchRequest);
setSearchRequest('What Does a Queen Bee look like?');
}
return (
<div className='search-contain'>
<form className='search-form-contain' onSubmit={handleSubmit}>
<label className='search-label'>Search:</label>
<input type='text' placeholder="Search for a video..." className='search-input' value={searchRequest} onChange ={(event) => setSearchRequest(event.target.value)} />
<button className='search-button'>Search</button>
</form>
</div>
);
}
export default SearchBar;```
import React from "react";
import "./VideoPlayer.css";
const VideoPlayer = (props) => {
return (
<div>
<iframe
id="ytplayer"
title="MyPlayer"
type="text/html"
width="640"
height="360"
src={`https://www.youtube.com/embed/${props.videoId}?autoplay=1&origin=http://example.com`}
frameBorder="0">
</iframe>
<div className="video-details">
<h3>{props.title}</h3>
<p>{props.description}</p>
</div>
<div className="video-details">
</div>
<div className="flex-container">
{props.relatedVideos.map((video, index) => {
if(video.snippet){
return (
<div key={index} className="flex-item">
<div>
<img src={video.snippet.thumbnails.medium.url} alt="" />
</div>
<div>
<h6 >{video.snippet.title}</h6>
</div>
</div>
);
} else {
return null;
}
})}
</div>
</div>
);
}
export default VideoPlayer;
VideoPage.js
import React, {useEffect, useState } from "react";
import { Link } from "react-router-dom";
import "./VideoPage.css";
import SearchBar from "../../components/SearchBar/SearchBar";
import axios from 'axios'
import VideoPlayer from "../../components/VideoPlayer/VideoPlayer";
import { KEY } from "./../../localKey"
const VideoPage = () => {
const [searchResults, setSearchResults] = useState('');
const [videoId, setVideoId] = useState("");
const [description, setDescription] = useState("");
const [title, setTitle] = useState("");
const [relatedVideos, setRelatedVideos] = useState([]);
useEffect(() => {
getSearchResults();
},[])
async function getSearchResults(searchTerm='Bees'){
let response = await axios.get(`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${searchTerm}&type=video&maxResults=1&key=${KEY}`);
setVideoId(response.data.items[0].id.videoId)
setDescription(response.data.items[0].snippet.description)
setTitle(response.data.items[0].snippet.title)
setSearchResults(response.data.items)
console.log(response.data.items)
}
useEffect(() => {
const fetchRelatedVideos = async () => {
try {
let response = await axios.get(`https://www.googleapis.com/youtube/v3/search?key=${KEY}&part=snippet&maxResults=3&type=video&relatedToVideoId=${videoId}`, {
});
setRelatedVideos(response.data.items);
} catch (error) {
console.log(error.message);
}
};
fetchRelatedVideos();
}, [videoId]);
return (
<div>
<div className="video-reg-contain"></div>
<div><SearchBar getSearchResults={getSearchResults}/></div>
<div className = 'video-contain'>
<div className="video-container">
<div className='video-player'>
<VideoPlayer videoId={videoId}
description={description}
title={title}
relatedVideos={relatedVideos}/>
</div>
</div>
</div>
</div>
);
};
export default VideoPage;
Related
Thanks for the help in advance. Currently, I am learning react. As a part of learning, I'm working on a basic expense listing app. In it, I was able to list the data entered through the form. But the problem is that when the new data is entered the previous one gets disappeared. I want to list the current as well as the previous data. Can anyone help me to resolve this.
App.js
import React, { useState, Fragment } from "react";
import ExpenseAddForm from "./ExpenseAddForm/ExpenseAddform";
import ExpenseList from "./ExpenseList/ExpenseList";
const App = () => {
const [expensesData, setExpensesData] = useState("");
const FormData = (datas) => {
setExpensesData(datas);
};
return (
<Fragment>
<div className="new-expense">
<ExpenseAddForm FormData={FormData} />
</div>
<ExpenseList listDatas={expensesData}></ExpenseList>
</Fragment>
);
};
export default App;
ExpenseAddform.js
import React, { useState } from "react";
import "./ExpenseAddForm.css";
const ExpenseAddForm = (props) => {
const [title, setTitle] = useState("");
const [amount, setAmount] = useState("");
const [date, setDate] = useState("");
const titleHandler = (e) => {
setTitle(e.target.value);
};
const amountHandler = (e) => {
setAmount(e.target.value);
};
const dateHandler = (e) => {
setDate(e.target.value);
};
const formSubmitHandler = (event) => {
event.preventDefault();
const formData = {
title: title,
amount: amount,
date: date,
};
props.FormData(formData);
setTitle("");
setAmount("");
setDate("");
};
return (
<form onSubmit={formSubmitHandler}>
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label>
<input type="text" onChange={titleHandler} value={title} />
</div>
<div className="new-expense__control">
<label>Amount</label>
<input type="number" onChange={amountHandler} value={amount} />
</div>
<div className="new-expense__control">
<label>Date</label>
<input type="date" onChange={dateHandler} value={date} />
</div>
</div>
<div className="new-expense__actions">
<button type="submit">Cancel</button>
<button type="submit">Add Expense</button>
</div>
</form>
);
};
export default ExpenseAddForm;
ExpenseList.js
import React from "react";
import ExpenseItem from "./ExpenseItem/ExpenseItem";
import ExpenseDateFilter from "./ExpenseDateFilter/ExpenseDateFilter";
import "./ExpenseList.css";
const ExpenseList = (props) => {
return (
<div className="expenses">
<ExpenseDateFilter />
<ExpenseItem expenseInfos={props.listDatas} />
</div>
);
};
export default ExpenseList;
ExpenseItem.js
import React from "react";
// import ExpenseDate from "../ExpenseDate/ExpenseDate";
import "./ExpenseItem.css";
const ExpenseItem = (props) => {
return (
<div className="expense-item">
{/* <ExpenseDate enteredDate={props.expenseInfos.date} /> */}
<div className="expense-item__description">
<h2>{props.expenseInfos.title}</h2>
{/* <div className="expense-item__price">${props.expenseInfos.amount}</div> */}
</div>
</div>
);
};
export default ExpenseItem;
ExpenseDateFilter.js
import React from "react";
const ExpenseDateFilter = () => {
return (
<div className="expenses-filter">
<div className="expenses-filter__control">
<label>Filter by year</label>
<select>
<option value="2022">2022</option>
<option value="2021">2021</option>
<option value="2020">2020</option>
<option value="2019">2019</option>
</select>
</div>
</div>
);
};
export default ExpenseDateFilter;
The problem with your code is on each submit your overriding the expensesData with the new data
instead you need to do
const FormData = (datas) => {
setExpensesData([...expensesData,datas]);
};
now you have list of data next you need to handle multiple expenses data in ExpenseList.js
{props.listDatas.map((data,key)=>
<ExpenseItem expenseInfos={data} />
)}
and it should be done here is a link of a working example https://codesandbox.io/s/xenodochial-grass-g2k1fh?file=/src/App.js:467-476
I have such a problem. I want to receive a notification after entering a keyword in the input and submitting. If there is a movie, then the movies should be listed, if there is not movies, let the toast notification appear. But the problem, even movies there are still toast works. How can i fix it? I want only when there are no movies for example search results doesnt find any film that toast will come. But toast comes every moment
import React, { useState } from "react";
import axios from "axios";
import { API_KEY } from "../../utils/api";
import MovieItem from "../../components/MovieItem/MovieItem";
import { Button, Input, Form } from "antd";
import "antd/dist/antd.min.css";
import "./Search.scss";
import Loader from "../../components/Loader/Loader";
import { toast } from "react-toastify";
const Search = () => {
const [movies, setMovies] = useState([]);
const [searchTerm, setSearchTerm] = useState("");
const [loading, setLoading] = useState(false);
const fetchSearch = () => {
setLoading(true)
axios
.get(
`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&language=en-US&query=${searchTerm}&page=1&include_adult=false`
)
.then((res) => res.data)
.then((res) => {
if (!res.errors) {
setMovies(res.results);
setLoading(false)
if (movies.length === 0) {
toast("Movies doesnt find");
}
setSearchTerm("");
console.log("yes");
} else {
setMovies([]);
console.log("no");
}
});
};
const handleChange = (e) => {
setSearchTerm(e.target.value);
};
return (
<>
<div className="search">
<div className="container">
<div className="row">
<div className="col-lg-12 mb-3 mt-3">
<h2>Suggest me</h2>
</div>
<Form onFinish={fetchSearch}>
<Form.Item>
<Input
value={searchTerm}
onChange={handleChange}
placeholder="Search Movies"
/>
</Form.Item>
<Button htmlType="submit">Search</Button>
</Form>
</div>
</div>
</div>
<div className="movies">
<div className="container-fluid">
<div className="row">
{loading
?
<Loader/>
: movies?.map((movie, index) => (
<div className="col-lg-3 p-3" key={index}>
<MovieItem movie={movie} page='top_Rated'/>
</div>
))}
</div>
</div>
</div>
</>
);
};
export default Search;
Problem is solved. Res.results.length was my problem's solution
I'm trying to display data from the OMdb API, but every time I try using my method nothing works.
I want to display the movie posters onto a slider using Spline.js, I was able to successfully do so whenever I manually put in the JSON data into the state but now I want to get the data from the API and I'm coming across this props.movie.map is not a function error all the way in an external component.
Heres the project on CodeSandbox just in case
https://codesandbox.io/s/github/JojoDuke/reactmoviesapp?file=/src/App.js
App.js
/* eslint-disable react-hooks/exhaustive-deps */
import React, { useState, useEffect } from 'react';
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css"
import MoviesList from "./components/MoviesList";
import ListHeading from './components/ListHeading';
import { SearchBox } from './components/SearchBox';
import AddFavourites from './components/AddFavourites';
import RemoveFavourites from './components/RemoveFavourites';
import MainMovie from './components/MainMovie';
import Navbar from './components/Navbar';
import Footer from './components/Footer';
const App = () => {
const [movies, setMovies] = useState([]);
const [searchValue, setSearchValue] = useState("");
const [favourites, setFavourites] = useState([]);
// Backup
// const getMovie = async () => {
// const url = 'http://www.omdbapi.com/?i=tt3896198&apikey=ce990560';
// const res = await fetch(url);
// const data = await res.json();
// const responseJson = JSON.parse(data);
// setMovies(responseJson);
// }
const API_KEY = "91d62f4";
const url = `http://www.omdbapi.com/?i=tt3896198&apikey=${API_KEY}`;
const getMovies = async () => {
try {
const response = await fetch(url);
const data = await response.json()
setMovies(data);
} catch (e) {
console.error(e.toString);
}
}
// FUNCTIONS
useEffect(() => {
getMovies();
}, []);
useEffect(() => {
const movieFavourites = JSON.parse(
localStorage.getItem('react-movie-app-favourites')
);
if (movieFavourites) {
setFavourites(movieFavourites);
}
}, []);
const saveToLocalStorage = (items) => {
localStorage.setItem('react-movie-app-favourites', JSON.stringify(items));
}
const addFavouriteMovie = (movie) => {
const newFavouriteList = [...favourites, movie];
setFavourites(newFavouriteList);
saveToLocalStorage(newFavouriteList);
}
const removeFavouriteMovie = (movie) => {
const newFavouriteList = favourites.filter((favourite) => favourite.imdbID !== movie.imdbID);
setFavourites(newFavouriteList);
saveToLocalStorage(newFavouriteList);
}
// FUNCTIONS CLOSE
return (
<div>
{/* Navigation Bar */}
<div>
<Navbar />
</div>
<div className="row d-flex align-items-center mb-5">
{/* Main Movie Area */}
<MainMovie/>
{/* <SearchBox
searchValue={searchValue}
setSearchValue={setSearchValue}/> */}
</div>
{/* Movies List */}
<ListHeading heading="Trending" />
<div>
<MoviesList
movies={movies}
handleFavouritesClick={addFavouriteMovie}
favouriteComponent={AddFavourites}/>
</div>
{/* List 2 */}
<div className="row d-flex align-items-center mt-4 mb-4">
<ListHeading heading="Cinetime Originals" />
</div>
<div>
<MoviesList
movies={movies}
handleFavouritesClick={addFavouriteMovie}
favouriteComponent={AddFavourites}/>
</div>
{/* List 3 */}
<div className="row d-flex align-items-center mt-4 mb-4">
<ListHeading heading="Classics" />
</div>
<div>
<MoviesList
movies={movies}
handleFavouritesClick={addFavouriteMovie}
favouriteComponent={AddFavourites}/>
</div>
<Footer />
</div>
);
};
export default App;
MoviesList.js(where I'm getting the error)
import React from 'react';
import { Splide, SplideSlide } from '#splidejs/react-splide';
//import '#splidejs/splide/dist/css/themes/splide-default.min.css';
const MoviesList = (props) => {
//const FavouriteComponent = props.favouriteComponent;
const movieSplide = props.movies.map((movie, index) => {
return(
<SplideSlide>
<div className="movie-div">
<div className="overlay"></div>
<img
className="movie-item shadow"
src={movie.Poster}
alt='movie'></img>
</div>
</SplideSlide>
);
});
return(
<Splide options={{
rewind: false,
autoWidth: true,
perPage: 6,
perMove: 2,
pagination: false,
gap: '1em',
focus: 'center',
type: 'slide',
easing: 'ease',
arrows: true
}}>
{movieSplide}
</Splide>
);
};
export default MoviesList;
I have json data file. I want to make a search with the names of the data and display the typed names when I click the search button.
I get the value of input in the console when I type something however I am not able to display it on the screen
How can I display the value of this input ?
my code is below
PostResults.jsx
import React from "react";
const PostResults = (props) => {
const {name} = props.posts
return(
<div className="">
<p className="titles">{name}</p>
</div>
)
}
export default PostResults
Posts.jsx
import React, { useState, useEffect } from "react";
import PostResults from './PostResults'
const Posts = (props) => {
const [posts, setPosts] = useState([]);
const [searchTerm,setSearchTerm]=useState([]);
const getData = () => {
fetch('data.json')
.then(response => {
return response.json()
//console.log(response)
})
.then(data => {
setPosts(data)
console.log(data)
})
}
useEffect(() => {
getData()
},[])
const submitHandler = (event) => {
event.preventDefault()
{searchTerm ? searchTerm : console.log("none")}
}
return(
<div className="">
<input
type="text"
placeholder="Search Anything"
name="query"
onChange={e => setSearchTerm(e.target.value)}
className="search-input"
/>
<button
onClick={submitHandler}
type="submit"
className="search-button"
>
<i className="fas fa-search"></i>
</button>
{posts.map(posts => (
<PostResults key={posts.id} posts={posts}/>
))}
</div>
)
}
export default Posts
App.jsx
import React from "react";
import "./style.css";
import 'bootstrap/dist/css/bootstrap.min.css'
import Posts from './components/Posts'
export default function App() {
return (
<div className="container">
<div className="row">
< Posts />
</div>
</div>
);
}
Hi people Am new in react js, i have a problem in display data , in my application i fetched data but i couldn't be display in web page don't know where Am wrong please try to fix my error or tell me what should i do?
console data
https://ibb.co/1MfgDgW
Star.js
import Axios from 'axios';
import React, { useState, useEffect } from 'react';
import './Star.css';
import Planet from './Planet';
import People from './People';
const Star = () => {
const [search, setSearch] = useState('');
const [people, setPeople] = useState([]);
const [planet, setPlanet] = useState([]);
const onSubmit = (e) => {
e.preventDefault();
if (search === "") {
alert("please Enter some value");
}
}
useEffect(() => {
async function fetchPeople() {
const res = await Axios.get("https://swapi.dev/api/people/?format=json");
console.log(res.data.results);
setPeople(res.data.results);
}
async function fetchPlanet() {
const res = await Axios.get("https://swapi.dev/api/planets/?format=json");
console.log(res.data.results);
setPlanet(res.data.results);
}
fetchPeople();
fetchPlanet();
}, [])
// console.log("people", people);
// console.log("planet", planet);
return (
<div>
<div className='container'>
<h2>Star War </h2>
<div className='jumbotron'>
<input type="text"
className="form-control"
placeholder='Search...'
value={search}
onChange={(e) => setSearch(e.target.value)} />
<span><button className='btn btn-secondary' onClick={onSubmit}>Search</button></span>
</div>
<People people={people}/>
<Planet planet={planet}/>
</div>
</div>
)
}
export default Star;
People.js
import React from 'react';
const People = (props) => {
const { data } = props;
return (
<div className="row">
{data && data.map((people, i) => {
return (
<div className="col-md-3" key={i}>
<div className="card">
<div className="card-body">
<h4>{people.data.results[0].name}</h4>
</div>
</div>
</div>
)
})}
</div>
);
};
export default People;
Planet.js
import React from 'react';
const Planet = (props) => {
const { data } = props;
return (
<div className="row">
{data && data.map((planet, i) => {
return (
<div className="col-md-3" key={i}>
<div className="card">
<div className="card-body">
<h4>{planet.data.results[0].name}</h4>
</div>
</div>
</div>
)
})}
</div>
);
};
export default Planet;
App.js
This is the App.js file where i include my all components
import './App.css';
import Star from './Star';
import People from './People';
import Planet from './Planet';
function App(props) {
const { people, planet } = props;
return (
<div className="App">
<Star
people={people}
planet={planet}
/>
<People data={people} />
<Planet data={planet} />
</div>
);
}
export default App;
You pass people and planet as props, but using it as data prop:
<Planet planet={planet}/>
const Planet = (props) => {
// change to this, people too
const { planet } = props;
};
You're passing people and planet as props to App but you're performing the fetching in Star.js.
You might need to restructure your app so that data fetching is done by App and then pass down everything as props.
function App(props) {
const { people, planet } = props;
return (
<div className="App">
<Star people={people} planet={planet} />
<People data={people} />
<Planet data={planet} />
</div>
);
}