Can't load image from an API using React - javascript

I successfully load data from the OpenDota API but somehow, the images
are broken when I pass the image props in my Heroes.js
here is the Component where I load the API.
HeroStats.js
import React, { Component } from 'react'
import Sidebar from "./Sidebar";
import Heroes from "./Heroes"
import "./App.css"
import axios from "axios";
const URL = "https://api.opendota.com/api/heroStats";
class HeroStats extends Component {
state = {
data: []
}
componentDidMount() {
axios.get(URL)
.then(res => {
this.setState({
data: res.data
});
});
}
render() {
const Stats = this.state.data.map(stat => (
<Heroes
key={stat.id}
id={stat.id}
name={stat.name}
localized_name={stat.localized_name}
img={stat.img}
icon={stat.icon}
pro_win={stat.pro_win}
pro_pick={stat.pro_pick}
pro_ban={stat.pro_ban}
/>
))
return (
<div>
{Stats}
</div>
)
}
}
export default HeroStats;
and here where I pass my props.
Heroes.js
import React from 'react'
const Heroes = (props) => (
<div>
<h1>{props.localized_name}</h1>
<img src={props.img} />
<img src={props.icon} />
<h1>{props.pro_win}</h1>
<h1>{props.pro_pick}</h1>
<h1>{props.pro_ban}</h1>
</div>
)
export default Heroes;
also if I use other tag like <h1>{props.img}</h1> it shows the image file path. did I miss something that i should include?

the value of img is not the full url you need to do this
const Heroes = (props) => (
<div>
<h1>{props.localized_name}</h1>
<img src={"https://api.opendota.com" + props.img} />
<img src={"https://api.opendota.com" + props.icon} />
<h1>{props.pro_win}</h1>
<h1>{props.pro_pick}</h1>
<h1>{props.pro_ban}</h1>
</div>
)

Related

Warning: Each child in a list should have a unique "key" prop. Check the render method of `Cart`. Teact.js

I'm making E-commerce website just I want to add to cart . when I click add to cart button then add Product on my cart but its showing error , and I use a lot of method but I did not solve. can you explain cleanly
getting this error I tried to fixed but I could not , where I am making mistake
react_devtools_backend.js:4012 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `Cart`. See https://reactjs.org/link/warning-keys for more information.
at div
at Cart (http://localhost:3000/main.f51a13b4a1752c213b98.hot-update.js:34:71)
at RenderedRoute (http://localhost:3000/static/js/bundle.js:49574:5)
at Routes (http://localhost:3000/static/js/bundle.js:49997:5)
at div
at App
at CartContext (http://localhost:3000/static/js/bundle.js:713:5)
at ProductContext (http://localhost:3000/static/js/bundle.js:806:5)
at Router (http://localhost:3000/static/js/bundle.js:49935:15)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:48282:5)
Home page
import React from 'react';
import { CartState } from "../Context/ProductContext";
import Navbar from "../Components/Navbar/Navbar";
import SingleProduct from "../Components/Products/SingleProduct";
import "../Components/Products/SingleProduct.css";
import { CartStatus } from "../Context/CartContext";
const Home = () => {
//custom hook useContext
const { Product} = CartState();
console.log("Product:", Product);
return (
<>
<Navbar/>
<div className="Product_wrapper">
{Product?.map((products, i) => (
<SingleProduct key={products.id} products={products}/>
)
)}
</div>
</>
)
}
Single Product
import React from 'react';
import "../Products/SingleProduct.css";
import { CartStatus } from "../../Context/CartContext";
//Add to product using Dispatch
const SingleProduct = ({ products }) => {
const {Cart , dispatch} = CartStatus()
// console.log("DEMON:", Cart);
const addToCart = (products)=>{
dispatch({ type:"ADD_CART", playload:products})
}
return (
<div className="product_container">
<img src={products.image} className="img" alt={products.name} />
<h1>{products.title}</h1>
<span>₹{products.price}</span>
<button
onClick={(products) =>{
addToCart(products)
}}
className="btn">Add</button>
</div>
)
}
export default SingleProduct;
Cart
import React from 'react';
import AddToCart from "../Components/Cart/AddToCart";
import { CartStatus } from "../Context/CartContext";
import "../Components/Products/SingleProduct.css";
// import { CartState } from "../Context/ProductContext";
const Cart = () => {
const {Cart, dispatch} = CartStatus();
console.log("LLL:" ,Cart);
return (
<div className="Product_wrapper">
{Cart.map((products,i) =>(
<div className="product_container" key={products.id}>
<img src={products.image} className="img" alt={products.name} />
<h1>{products.title}</h1>
</div>
))}
</div>
)
}
export default Cart;
I'm using UseContext and UseReducer for make

ReactJs: How to get api data in child component with props?

I am trying to call api data only once thats way I call api in home.js file with componentdidmount in class component and i want to render this data in many child components with functional components.when i call api in every each child component,its work but when i try to call with props coming only empty array by console.log please help.
import React from 'react'
import '../styles/home.css'
import axios from 'axios';
import Teaser from './Teaser'
import Second from './Second'
import Opening from './Opening'
import Menu from './Menu'
export default class Home extends React.Component {
state = {
posts: []
}
componentDidMount() {
axios.get("https://graph.instagram.com/me/media?fields=id,caption,media_url,permalink,username&access_token=IGQ")
.then(res => {
const posts = res.data.data;
this.setState({ posts });
})
}
render() {
return (
<>
<Teaser/>
<Second/>
<Opening/>
<Menu posts={this.state.posts}/>
</>
)
}
}
import React from 'react'
import axios from 'axios';
function Menu(props) {
const {posts} = props.posts;
console.log(props);
return (
<>
{posts.map(
(post) =>
post.caption.includes('#apegustosa_menu') &&
post.children.data.map((x) => (
<div className="menu_item" key={x.id}>
<img className="menu_img" src={x.media_url} alt="image" />
</div>
)),
)}
</>
)
}
export default Menu

How to implement onClick componentDidMount() in React using Axios

I am trying to make a movie search function using React, Axios, and movieDB API. The functionality I am trying to implement right now is typing in a movie into the search bar and clicking the submit button will return the movie title as an H1 element.
My onClick function does not work: <button onClick={(e)=>clickHandler()}>submit</button>
componentDidMount() will work only when the page refreshes and you cannot search for anything as the submit button is broken.
I am not sure how to implement this, but I would also not mind if I could get it to search by hitting enter instead of using a button, whichever is easier.
Here is my code so far.
App.js
import React from "react"
import Movielist from './components/Movielist'
function App() {
return (
<div>
<input type="search" id="search" />
<button onClick={(e)=>clickHandler()}>submit</button>
<h1 id="title">title</h1>
<Movielist />
</div>
)
}
export default App
Movielist.js
import React from 'react';
import axios from 'axios';
export default class Movielist extends React.Component {
state = {
title: ""
}
componentDidMount() {
const API_KEY = '***********************';
const query = document.getElementById('search').value;
axios.get(`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&query=${query}`)
.then(res => {
const title = res.data['results'][0]['title'];
this.setState({ title });
})
}
render() {
return (
<h1>{this.state.title}</h1>
)
}
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App />,
document.getElementById('root')
);
import React from 'react';
import axios from 'axios';
export default class Movielist extends React.Component {
state = {
title: ""
}
clickHandler = (event) => {
if (event.keyCode === 13) {
const query = event.target.value;
const API_KEY = '***********************';
axios.get(`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&query=${query}`)
.then(res => {
const title = res.data['results'][0]['title'];
this.setState({ title });
})
}
}
render() {
return (
<input type="search" id="search" onKeyDown={event => this.clickHandler(event)} />
<h1>{this.state.title}</h1>
)
}
}
You should call API to get the movie list after hitting the button, then pass the data that you've got to Movielist. Try this:
In App.js:
import React from "react"
import axios from 'axios'
import Movielist from './components/Movielist'
function App() {
const [movieList, setMovieList] = React.useState([])
const handleOnSubmit = () => {
const API_KEY = '***********************';
const query = document.getElementById('search').value;
axios.get(`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&query=${query}`)
.then(res => {
const title = res.data['results'][0]['title'];
setMovieList(res.data['results'])
})
}
return (
<div>
<input type="search" id="search" />
<button onClick={handleOnSubmit}>submit</button>
<h1 id="title">title</h1>
<Movielist movieList={movieList}/>
</div>
)
}
export default App
In Movielist.js:
import React from 'react';
const Movielist = ({movieList}) => {
return (
<div>
{
movieList.map(movie => <h1 key={movie.key}>{movie.title}</h1>)
}
<div/>
)
}
}
export default Movielist
import React, {useState} from "react"
import axios from 'axios';
import Movielist from './components/Movielist'
const [title, setTitle] = useState("")
const API_KEY = '***********************'
function App() {
const clickHandler = () => {
const query = document.getElementById('search').value;
axios.get(`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&query=${query}`)
.then(res => {
const title = res.data['results'][0]['title'];
setTitle(title);
})
}
return (
<div>
<input type="search" id="search" />
<button onClick={clickHandler}>submit</button>
<h1 id="title">title</h1>
<Movielist title={title} />
</div>
)
}
export default App
just move call api handle to your onclik func then pass title props to movie list
If you want to query the API after user push submit button. You should put your call to API in the call handler, then pass the state from App to MovieList as props
export class App extends React.Component {
state = {
title: ""
}
clickHandler() {
const API_KEY = '***********************';
const query = document.getElementById('search').value;
axios.get(`https://api.themoviedb.org/3/search/movie?api_key=${API_KEY}&query=${query}`).then(res => {
const title = res.data['results'][0]['title'];
this.setState({ title });
});
}
render() {
return (
<div>
<input type="search" id="search" />
<button onClick={(e)=>clickHandler()}>submit</button>
<h1 id="title">title</h1>
<Movielist list={this.state.title}/>
</div>
)
}
}
export class MovieList extends React.Component {
render() {
<h1>{this.props.title}</h1>
}
}
Alternatively, you can wrap the input in a element and use onSubmit + evt.preventDefault() instead, by doing so you can handle button click and pressing "Enter" to submit.

React-Paginate is not clickable

I have been trying to use React-paginate library for pagination, however, the buttons formed by it is not clickable,i don't understand what i am doing wrong
And there are no example given, or no question asked
What would be the correct way of using this pagination
Here is the code of my App.js
import React, { Component } from 'react';
import './App.css';
import Navbar from '../src/components/navbar/navbar'
import SearchIt from '../src/components/searchField/search'
import Container from 'react-bootstrap/Container'
import Card from '../src/components/cards/cards'
import Axios from 'axios'
import Pagination from '../src/components/pagination/paginating'
class App extends Component {
state={
fetchedData:[]
}
componentDidMount(){
Axios.get('http://localhost:3000/1').then((responseData)=>{
//console.log(responseData.data)
this.setState({fetchedData:responseData.data})
}).catch((err)=>{
console.log(err)
})
}
handlePageClicked = data => {
let selected = data.selected;
console.log(selected)
};
render() {
return (
<div className="App">
<Navbar/>
<Container>
<SearchIt/>
<Card data={this.state.fetchedData}/>
<Pagination handlePageClick={this.handlePageClicked}/>
</Container>
</div>
);
}
}
export default App;
And here is the code for paginating.js
import React,{Component} from 'react'
import ReactPaginate from 'react-paginate';
import './paginateStyle.css'
const page = (props)=>{
return(
<ReactPaginate
previousLabel={'previous'}
nextLabel={'next'}
breakLabel={'...'}
breakClassName={'break-me'}
pageCount={10}
marginPagesDisplayed={2}
pageRangeDisplayed={5}
onPageChange={props.handlePageClick}
containerClassName={'pagination'}
subContainerClassName={'pages pagination'}
activeClassName={'active'}
/>
)
}
export default page
These button are not clickable
I did a quick sample and it worked.
import ReactPaginate from 'react-paginate';
const Pagination = (props) => {
return (
<ReactPaginate
previousLabel={'previous'}
nextLabel={'next'}
breakLabel={'...'}
breakClassName={'break-me'}
pageCount={10}
marginPagesDisplayed={2}
pageRangeDisplayed={5}
onPageChange={props.handlePageClick}
containerClassName={'pagination'}
subContainerClassName={'pages pagination'}
activeClassName={'active'}
/>
)
}
class App extends Component {
state = {
selectedPage: 0
}
handlePageClicked = data => {
let selected = data.selected;
this.setState({
selectedPage: selected
})
console.log(selected)
};
render() {
return (
<React.Fragment>
<div>You selected: {this.state.selectedPage}</div>
<div className="App">
<Pagination handlePageClick={this.handlePageClicked} />
</div>
</React.Fragment>
);
}
}
There could be something in paginateStyle.css which is making the Pagination not work properly or some other CSS in your application.
EDIT:
From comments, a ui component with higher z index was over them and was not visible/clickable

Class component is rerendering in loop

I'm trying to build a simple youtube app using youtube-api-search. There's two main portion of the app ie. VideoDetail & VideoList. VideoDetail is intended to show/play the video whereas VideoList is for displaying a list of five videos with their titles.
Now, the issue is, top section of my app ie. is getting re-rendered continuously inside a loop. I cant figure out why that is. I app is really simple it doesn't even have any lifecycle methods. Please help me to figure out the error.
App.js (It is imported into index.js where it gets rendered)
import React, { Component } from 'react';
import YTSearch from 'youtube-api-search';
import SearchBar from './components/search_bar';
import VideoList from './components/video_list';
import VideoDetail from './components/video_detail';
const API_KEY = 'AIzaSyC----key------N7khtCs';
class App extends Component {
constructor(props){
super(props);
this.state = {
videos: [],
selectedVideo: null
};
console.log('sth.');
YTSearch({key: API_KEY, term: 'surfboards'}, (videos) => {
this.setState({
videos: videos,
selectedVideo: videos[0]
});
});
}
render(){
return (
<div>
{console.log('indexx')}
<VideoDetail video={this.state.selectedVideo} />
<VideoList
onVideoSelect={selectedVideo => this.setState({selectedVideo})}
videos={this.state.videos}
/>
</div>
);
};
}
export default App;
video_detail.js
import React from 'react';
const VideoDetail = ({video}) => { //accesssing props elements direcly
if(!video){
return <div>Loading Details</div>;
}
const videoId = video.id.videoId;
const url = `https//www.youtube.com/embed/${videoId}`;
return (
<div className="video-detail col-md-8">
<div className="embed-responsive embed-responsive-16by9">
<iframe className="embed-responsive-item" src={url}></iframe>
</div>
<div className="details">
<div>{video.snippet.title}</div>
<div>{video.snippet.description}</div>
</div>
</div>
);
};
export default VideoDetail;
video_list.js
import React from 'react';
import VideoListItem from './video_list_item';
const VideoList = props => {
const videoItems = props.videos.map((video) => {
console.log(video);
return (
<VideoListItem
onVideoSelect={props.onVideoSelect}
key={video.etag}
video={video} />
);
});
return (
<ul className="col-md-4 list-group">
{videoItems}
</ul>
);
};
export default VideoList;
video_list_item.js
import React from 'react';
const VideoListItem = ({video, onVideoSelect}) => { //pulling from props
const imageUrl = video.snippet.thumbnails.default.url;
return(
<li onClick={() => onVideoSelect(video)} className="list-group-item">
<div className="video-list media">
<div className="media-left">
<img className="media-object" src={imageUrl} />
</div>
<div className="media-body">
<div className="media-heading">{video.snippet.title}</div>
</div>
</div>
</li>
);
}
export default VideoListItem;
Someone, please explain me what is the issue here. I want to understand.
Finally figured out the issue:
I was because : was not present in the url.
const url = https://www.youtube.com/embed/${videoId};

Categories