movie-trailer npm isn't working properly in my netflix clone project - reactjs

I've made a netflix clone using React.js, firebase, and have used TMDB api for movie database.
I've also used react-youtube and movie-trailer npm.
So it has this feature that every time I click on any movie poster, it's trailer must be played.
But for most of the movies, trailer doesn't shows up.
This is the error that I face -
movie-trailer: No TMDB Movie found with the current search terms, try searching https://www.themoviedb.org/search?query=Luis%20Miguel%3A%20The%20Series
TypeError: Failed to construct 'URL': Invalid URL
at Row.js:37
'This is the screenshot of errors I am facing on clicking maximum of movies'
I'm sharing the link of my github repo and deployed website as well for reference -
github - https://github.com/IshitaSharma3101/netflix-clone
website - https://netflix-clone-afb8b.web.app/
Row component code-
import React, { useState, useEffect } from "react";
import YouTube from "react-youtube";
import axios from "./axios";
import "./Row.css";
import movieTrailer from "movie-trailer"
const base_url = "https://image.tmdb.org/t/p/original/";
function Row({ title, fetchURL, isLargeRow }) {
const [movies, setMovies] = useState([]);
const [trailerURL, setTrailerURL] = useState("");
useEffect(() => {
async function fetchData() {
const request = await axios.get(fetchURL);
console.log(request.data.results);
setMovies(request.data.results);
return request;
}
fetchData();
}, [fetchURL]);
const opts = {
height: "390",
width: "100%",
playerVars: {
autoplay: 1,
},
};
const handleClick = (movie) => {
if (trailerURL) {
setTrailerURL("");
} else {
movieTrailer(movie?.name || movie?.title || movie?.original_title || "")
.then((url) => {
const urlParams = new URLSearchParams(new URL(url).search);
setTrailerURL(urlParams.get("v"));
})
.catch((error) => console.log(error));
}
};
return (
<div className='row'>
<h2>{title}</h2>
<div className='row__posters'>
{movies.map((movie) => (
<img
key={movie.id}
onClick={() => handleClick(movie)}
className={`row__poster ${isLargeRow && "row__posterLarge"}`}
src={`${base_url}${
isLargeRow ? movie.poster_path : movie.backdrop_path
}`}
alt={movie.name}
/>
))}
</div>
{trailerURL && <YouTube videoId={trailerURL} opts={opts} />}
</div>
);
}
export default Row;

I'm sure you are following the Clever Qazi tutorial as I'm doing. I think there is basically no solution for this problem. I also try to get the trailer of the movies by the ID that TMDB gives for every film but this method definitely doesn't work for mine. My conclusion is that movie-trailer is not working for certain kind of film or series...
You can prove yourself my conlclusion by typing on a terminal npx movie-trailer Cobra Kai
which is the command that allow you to use this package. Cobra Kai is a well know series but this "tool" doesn't find any trailer for it.

Use this instead.
movieTrailer(null ,{ tmdbId: movie.id })
.then((url)=>{
console.log("url is "+url);
const urlParams=new URLSearchParams(new URL(url).search);
console.log("urlParamsn"+urlParams);
setTrailerUrl(urlParams.get("v"));
})
.catch((error)=> console.log(error));
}
}
With this you can search for the movie with the tmdb id.

This error is coming becouse TMDB has not added ids for some videos if you want to play all video you just need need to change the genres of the Netflix Original Video from the path in request.js folder where you wrote your path becouse Netflix originals Videos has not linked with ids on TMDB.

Related

How to preset prop (logged in user) for React component unit test?

I'm rather new to testing React application, thank you for your time in advance for responding to a newbie question.
So I've been following tutorial on Full Stack Open and came across this challenge about writing tests for React. There is this component Blog which takes some props from App > Blog List > Blog, including one called 'user' which is the returned object from the login function storing username and token etc.
In the Blog's JSX there is a 'remove' button which is shown only to logged in users, controlled by its style determined by a function comparing the username of the original poster of the blog and that of the currently logged in user.
Right now I'm not writing test for username comparison function at all, but it just gets in the way because I can't seem to set a value for 'user' to be passed into the Blog component, and this error was returned during the test:
display: blog.user.username === user.username ? '' : 'none'
^
TypeError: Cannot read properties of undefined (reading 'username')
And here are the codes of the Blog component and the test at current state:
import { useState } from 'react'
const Blog = ({ blog, addLike, deleteBlog, user }) => {
const [showDetails, setShowDetails] = useState(false)
const showWhenDetailsTrue = { display: showDetails ? '' : 'none' }
const toggleDetails = () => {
setShowDetails(!showDetails)
}
const postedBySelf = async () => {
const style = await {
display: blog.user.username === user.username ? '' : 'none',
}
return style
}
return (
<div style={blogStyle}>
<div>
{blog.title} {blog.author}{' '}
<button onClick={toggleDetails}>{showDetails ? 'hide' : 'view'}</button>
</div>
<div style={showWhenDetailsTrue} className="defaultHidden">
<div>{blog.url}</div>
<div>
likes {blog.likes}
<button onClick={() => addLike(blog.id)}>like</button>
</div>
<div>{blog.author}</div>
<button onClick={() => deleteBlog(blog)} style={postedBySelf()}>
remove
</button>
</div>
</div>
)
}
export default Blog
The test file:
import React from 'react'
import '#testing-library/jest-dom/extend-expect'
import { render, screen } from '#testing-library/react'
import Blog from './Blog'
test('renders title and author, but not url or number of likes by default', async () => {
const blog = {
title: 'Blog title',
author: 'Blog author',
url: 'Blog url',
user: {
username: 'mockuser',
},
}
await render(<Blog blog={blog} user={{ username: 'mockuser' }} />)
screen.getByText('Blog title', { exact: false })
screen.getAllByText('Blog author', { exact: false })
const { container } = render(<Blog blog={blog} />)
const div = container.querySelector('.defaultHidden')
expect(div).toHaveStyle('display: none')
})
When the postedBySelf function and associated content are commented out the test is passed. My question is, how can I mock the 'user' object and pass it into the component during the test? I don't understand why it is undefined even if I explicitly declared its value.
Thanks again for your time and appreciate your advice.
Finally spotted my mistake, had to pass in the user in the second rendering of the Blog too.
I wasn't quite sure if I'm missing critical knowledge on this topic but this tutorial explains things very well and helped me spotted the issue in a way. Strongly recommended: https://www.youtube.com/watch?v=OVNjsIto9xM

Showing 404 error after hosting a webapp in react js

I have created a Blog web App using react Js , it is working fine on my local system but after hosting it ,it is showing 404 status code . I have used fake json-server package to launch on my local system but after hosting it with the github it is fetching no data from json file.
This is the webapp https://manishya1669.github.io/BlogWebApp/ and this is the code for Blogdetails and for more clearity you can see the whole code source on https://github.com/manishya1669/BlogWebApp
import { useHistory, useParams } from "react-router-dom";
import useFetch from "./useFetch";
const BlogDetails = () => {
const {id} = useParams();
const {data:blog, error,isPending} = useFetch('http://localhost:8000/blogs/' + id);
const history = useHistory();
const handleClick = () => {
fetch('http://localhost:8000/blogs/' + blog.id, {
method: 'DELETE'
}).then(() => {
history.push('/');
})
}
return (
<div className= "blog-details">
{isPending && <div> Loading</div> }
{error && <div>{error}</div>}
{ blog &&(
<article>
<h2>
{blog.title}
</h2>
<p> Written by {blog.author}</p>
<div>{blog.body}</div>
<button onClick={handleClick}>Delete</button>
</article>
)
}
</div> );
}
export default BlogDetails;
**Hope this is enough to make my self clear and appreciating those who are willing to help**
I found its solution , it was not following Cors policy because
I was running my whole Client side on port no 3000 and trying to receive data from port 8000, So due to two different port it was considering two different website where one is trying to retrieve data from other also that website was not secure . So to deal with this you have add a proxy server in your package.json for example
"name": "webapp",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8000",
Also you have to replace fetch('http://localhost:8000/blogs/' + blog.id,
with fetch('/blogs/' + blog.id,
const handleClick = () => {
fetch(/'blogs'/+ blog.id, {
method: 'DELETE'
}).then(() => {
history.push('/');
})
}
If you find and any mistake please let me know it would help me to learn more.

Vercel: ERROR Error: The package "esbuild-linux-64" could not be found, and is needed by esbuild

Hope you all are having a good time. I am working on a simple NextJs application where I want to have multiple subdomains in it. I am deploying the application on vercel.
What my application does is it have a simple textarea where you write MDX, you click the Publish button and it will save that MDX into firebase firestore. Below the textarea it shows the list of all the pages that have been published before.
The application renders the list of all the pages like with name of the page which is randomly generated as the subdomain while the actual domain comes later like the following.
a-mdx-page.mydomain.app
When I open that URL it will fetch the page MDX from firestore and uses next-mdx-remote package to serialize and render the MDX. The reason for using the next-mdx-remote package is that we can add react components in MDX and it can render as normal react components. I already have a custom domain because you cannot have a subdomain on top of a free subdomain in vercel free deployment.
All works fine on localhost and everything is as it should be but the problem is when I deploy the code on Vercel and navigate to subdomain it shows ERROR 500 on the website and shows the following error in the logs.
[GET] / 21:21:03:30
2021-10-24T16:21:04.018Z 8e52d5da-ff1f-4840-a09b-199233834a5d ERROR Error: The package "esbuild-linux-64" could not be found, and is needed by esbuild.
If you are installing esbuild with npm, make sure that you don't specify the
"--no-optional" flag. The "optionalDependencies" package.json feature is used
by esbuild to install the correct binary executable for your current platform.
at generateBinPath (/var/task/node_modules/esbuild/lib/main.js:1643:15)
at esbuildCommandAndArgs (/var/task/node_modules/esbuild/lib/main.js:1699:11)
at ensureServiceIsRunning (/var/task/node_modules/esbuild/lib/main.js:1856:25)
at Object.transform (/var/task/node_modules/esbuild/lib/main.js:1751:37)
at serialize (/var/task/node_modules/next-mdx-remote/dist/serialize.js:287:43)
at async getServerSideProps (/var/task/.next/server/pages/index.js:261:25)
at async Object.renderToHTML (/var/task/node_modules/next/dist/server/render.js:428:24)
at async doRender (/var/task/node_modules/next/dist/server/next-server.js:1144:38)
at async /var/task/node_modules/next/dist/server/next-server.js:1236:28
at async /var/task/node_modules/next/dist/server/response-cache.js:64:36 {
page: '/'
}
RequestId: 8e52d5da-ff1f-4840-a09b-199233834a5d Error: Runtime exited with error: exit status 1
Runtime.ExitError
From what I understand that the next-mdx-remote serialize function uses esbuild in it and when I deploy the application on vercel npm just doesn't downloads the platform specific package of it but may be I am wrong.
I have tried to search the solution for this but there is not any answers that helped me.
Following is all the code that the application uses.
import { useState } from "react"
import { collection, doc, getDoc, getDocs, setDoc } from "firebase/firestore"
import matter from "gray-matter"
import { MDXRemote } from "next-mdx-remote"
import { serialize } from "next-mdx-remote/serialize"
import {
uniqueNamesGenerator,
adjectives,
colors,
animals,
} from "unique-names-generator"
import { db } from "../utils/fire-client"
import Layout from "../components/Layout"
import { HOSTNAME } from "../config"
import MDXComponents from "../components/mdx"
export default function Index({ posts, isPage = false, mdxSource }) {
const [mdxCode, setMdxCode] = useState("# THIS IS MDX")
const [message, setMessage] = useState("")
const addPageToCollection = async (name, content) => {
const pagesCollection = collection(db, "pages")
await setDoc(doc(pagesCollection, name), {
name,
content,
})
}
function publishPage() {
const randomName = uniqueNamesGenerator({
dictionaries: [adjectives, colors, animals],
})
addPageToCollection(randomName, mdxCode)
setMessage(
"New Page Added: " + randomName + "\nReload page To see it in the list"
)
setTimeout(() => {
setMessage("")
}, 5000)
}
return (
<Layout>
{isPage ? (
<>
<header>
<nav>
<a href={"http://" + HOSTNAME}>
<a>👈 Go back home</a>
</a>
</nav>
</header>
<main>
<MDXRemote {...mdxSource} components={MDXComponents} />
</main>
</>
) : (
<>
<h1>Home Page</h1>
<textarea
name="mdxCode"
id="mdxCode"
value={mdxCode}
onChange={(e) => setMdxCode(e.target.value)}
className="w-full h-1/2 border-2 border-gray-400 p-2"
/>
<button className="btn btn-primary" onClick={publishPage}>
Publish
</button>
<div>{message}</div>
<ul>
<div className="mt-4 font-bold">Pages List</div>
{posts.map((post) => (
<li key={post.name}>
<a href={`http://${post.name}.${HOSTNAME}`}>{post.name}</a>
</li>
))}
</ul>
</>
)}
</Layout>
)
}
export async function getServerSideProps({ req, res }) {
const host = req.headers.host.split(".")
if (host[0] !== HOSTNAME.split(".")[0] && host[0] !== "www") {
const docRef = doc(db, "pages", host[0])
const docSnap = await getDoc(docRef)
if (docSnap.exists()) {
const { content, data } = matter(docSnap.data().content)
const mdxSource = await serialize(content, {
// Optionally pass remark/rehype plugins
mdxOptions: {
remarkPlugins: [],
rehypePlugins: [],
},
scope: data,
})
if (mdxSource) {
return {
props: {
isPage: true,
mdxSource,
},
}
}
} else {
return {
props: {
redirect: {
destination: "/",
},
},
}
}
}
const pagesCollection = collection(db, "pages")
const pagesSnapshot = await getDocs(pagesCollection)
const pagesList = pagesSnapshot.docs.map((doc) => doc.data())
if (pagesList.length > 0) {
return {
props: {
posts: pagesList,
},
}
}
return { props: { posts } }
}
Update esbuild to 0.13.4 or higher
npm i -D esbuild#0.13.4
See: https://github.com/evanw/esbuild/releases/tag/v0.13.4
If building with Docker this could be due to an incomplete .dockerignore file that doesn't ignore all your node_modules folder.

How to get 5 day weather forecast using React Hooks and OpenWeatherMap API

So I want to be able to show the 5 day weather forecast for a chosen city, using the OpenWeatherMap API and React.
I've seen a few tutorials online but they all use Class components, I want to use mine using a functional Component and the UseState hook.
I have this working code which allows me to get the CURRENT weather,location name and displays a little weather icon.
I want to be able to get the info for 5 days, and put it into a list. Specificially I want the high, low, main, description and an icon, for each day.
I'm really inexperienced at making API calls so I'm struggling to figure it out. I have my API key, and I think my API call should look something like this
https://api.openweathermap.org/data/2.5/weather?q=${placename},IE&appid=${apiKey}&units=metric
where placename is a prop I pass to it, and IE is my country code.
I was looking at this tutorial which does what I want, but it uses class-based components instead. I can't figure out how to do it without using classes.
https://medium.com/#leizl.samano/how-to-make-a-weather-app-using-react-403c88252deb
If someone could show me how to do this, that would be much appreciated. Here is my current code that gets just the current temperature.
export default function Weather (props) {
// State
const [apiData, setApiData] = useState({});
const [state, setState] = useState('Belfast');
var placename = props.placeprop
// API KEY AND URL
const apiKey = process.env.REACT_APP_API_KEY;
const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${placename},IE&appid=${apiKey}&units=metric`;
useEffect(() => {
fetch(apiUrl)
.then((res) => res.json())
.then((data) =>
setApiData(data),);
}, [apiUrl]);
return (
<div className="weather">
<div>
{apiData.main ? (
<div>
<img
src={`http://openweathermap.org/img/w/${apiData.weather[0].icon}.png`}
alt="weather status icon"
/>
<br/>
{apiData.name}
<br/>
{apiData.main.temp}° C
</div>
)
: (
<h1>Loading</h1>
)}
</div>
</div>
)
} ```
This is not a complete answer but I came across this question so I'm sharing what I have.
import React, {useEffect, useState} from 'react';
import css from './Weather.module.css';
function useOpenWeather ({apiKey, lat, lon, units = 'metric'}) {
const [apiData, setApiData] = useState(null);
const apiUrl = `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&appid=${apiKey}&units=${units}`;
useEffect(() => {
fetch(apiUrl)
.then((res) => res.json())
.then((data) => {
setApiData(data);
});
}, [apiUrl]);
return apiData;
}
function Weather ({lat, lon}) {
const weather = useOpenWeather({
apiKey: API_KEY
lat,
lon,
units: 'imperial'
});
return (
<div className={css.weather}>
{weather && weather.daily.slice(0, 5).map(d => (
<div>
<img
src={`http://openweathermap.org/img/w/${d.weather[0].icon}.png`}
alt={d.weather[0].main}
/>
<div>{d.temp.max} / {d.temp.min}</div>
</div>
))}
</div>
);
}
export default Weather;
.weather {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
grid-gap: 16px;
margin: 16px;
}

TypeError: Cannot read property 'getPosts' of undefined - useQuery hook, react Functional Components

I did try searching for the same question but all of those were of either angular or unrelated,
I am trying to make a Social app using MongoDB, Express, React, Node, Graphql with Apollo, I am following a video from freecodecamp : Link to the video
In that video everything worked fine but in his deployed version he is having the same error as mine
react_devtools_backend.js:2450 TypeError:
Cannot read property 'getPosts' of undefined
at ae (Home.js:14)
at Jo (react-dom.production.min.js:3274)
link to the deployed app
My Code: I am dropping a link to my github repo containing the whole project : Link to github
repo
Stack Overflow was throwing too many indentation issues so i have linked my github above as there
is too much of code
I'm using semantic-ui for styling
I'm using graphql the fetch posts from MongoDB
Apollo Client for rendering data
This is the error I am getting in the Home.js:
Screen Shot of the error:
Make it simpler to debug, instead:
const {
loading,
data: { getPosts: posts }
} = useQuery(FETCH_POSTS_QUERY);
do:
const { data, loading, error } = useQuery(FETCH_POSTS_QUERY);
if(data) {
console.log(data);
const { getPosts: posts } = data;
}
if(error) {
console.log(error);
return "error"; // blocks rendering
}
this works but not when data is there and not always
"not when data", "not always"??? weird ... 'posts' can be defined only if data exists ... accessing it when undefined will fail, always ... you must check 'data'
You can/should render items (posts) ONLY when:
!loading
AND
data != undefined - if(data) or (data && in JSX
{loading && <h1>Loading posts..</h1>}
{data && (
<Transition.Group>
{posts &&
posts.map((post) => (
<Grid.Column key={post.id} style={{ marginBottom: 20 }}>
<PostCard post={post} />
</Grid.Column>
))}
</Transition.Group>
)}
use this code like this
const { loading, data: { posts } = {} } = useQuery(FETCH_POSTS_QUERY);
You need to define the query operation like:
export const FETCH_POSTS_QUERY = gql`
query GetPosts {
getPosts {
// fields
}
}
`
Alternatively, you can make use of alias to easily reference them.
export const FETCH_POSTS_QUERY = gql`
query GetPosts {
posts: getPosts {
// fields
}
}
`
const {
loading,
data: { posts } // uses alias directly. no need to rename
} = useQuery(FETCH_POSTS_QUERY);
const { loading, data: { getPosts: posts } = {} } = useQuery(FETCH_POSTS_QUERY)
This should solve the problem
THIS WILL WORK
write data.getPosts inside the grid
const { loading ,data , error } = useQuery(FETCH_POSTS_QUERY);
if (error) return Error! ${error.message};
{loading ? (<h1>Loading posts...</h1>)
: (data.getPosts &&
data.getPosts.map((post) => (
<Grid.Column key={post.id} style= {{ marginBottom: 20}}>
<PostCard post={post} />
</Grid.Column>

Resources