React Display Data from API Fetch & Map - reactjs

i'm attempting to learn React by making a movie web app. Im trying to pull upcoming movies from a movie api, and display information from it, however i keep getting an error:
Line 37: Expected an assignment or function call and instead saw an
expression no-unused-expressions
Please excuse me as im not too familiar with this framework and im not a JS pro. Heres my code:
export default class Upcoming extends Component {
state = {
upcomingMovies: []
}
fetchUpcoming() {
fetch(`https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`)
// We get the API response and receive data in JSON format...
.then(response => response.json())
// ...then we update upcomingMovies State
.then(data =>
this.setState({
upcomingMovies: data.results
})
)
}
componentDidMount(){
this.fetchUpcoming();
}
render() {
return(
<Container>
{ this.state.upcomingMovies.map((upcomingMovie) => {
console.log(upcomingMovie);
const title = upcomingMovie.title;
console.log(title);
<h1>{title}</h1>
})}
</Container>
)
}
}

Map function should return something to generate ui.
export default class Upcoming extends Component {
state = {
upcomingMovies: []
}
fetchUpcoming() {
fetch(`https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`)
// We get the API response and receive data in JSON format...
.then(response => response.json())
// ...then we update upcomingMovies State
.then(data =>
this.setState({
upcomingMovies: data.results
})
)
}
componentDidMount(){
this.fetchUpcoming();
}
render() {
return(
<Container>
{ this.state.upcomingMovies.map((upcomingMovie) => (
<h1>{upcomingMovie.title}</h1>
))}
</Container>
)
}
}

You're missing a return statement in the last line of your map function. It should be return <h1>{title}</h1>

You should write fetchUpcoming by using arrow function. So, you can use this.setState() method on scope of fetchUpcoming function. EX:
const fetchUpcoming = async() {
try {
let response = await fetch(
`https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`,
);
let responseJson = await response.json();
return this.setState({
upcomingMovies: responseJson.data.results
})
} catch (error) {
console.error(error);
}
}

Related

Pagination in React-Redux

So I'm just trying to make a pagination component in react. Im currently using redux for my state management and using semantic-ui for the pagination component.
I have currently made a react component in my action.jsx file and have two other functions which one of them is for data fetching for my redux state and one other for the declaring the current active page value and set the new target url for data fetching.
export class Paginator extends React.Component {
state = {
page: [],
pages: []
}
handlePage(activePage) {
let pagenum = activePage;
let pagestring = pagenum.toString();
paginationUrl = '/api/v1/products/index/?page=' + pagestring; ----> Pass This Url
}
componentDidMount() {
axios.get("/api/v1/products/index", { withCredentials: true })
.then(response => {
this.setState({
page: response.data.page,
pages: response.data.pages
})
})
.catch(error => {
console.log("Check Login Error", error);
});
}
render() {
return(
<Pagination onPageChange={this.handlePage} size='mini' siblingRange="6"
defaultActivePage={this.state.page}
totalPages={this.state.pages}
/>
)
}
}
export function fetchProducts() {
return (dispatch) => {
dispatch(fetchProductsRequest())
axios
.get("To Here !")
.then(response => {
// response.data is the products
const products = response.data.products
dispatch(fetchProductsSuccess(products))
})
.catch(error => {
// error.message is the error message
dispatch(fetchProductsFailure(error.message))
})
}
}
The question is how am i able to pass the paginationUrl to the function below ? (Actually, there is no way i guess !).
Note: I am only able to use handlePage in the same component with the pagination component.
Waiting for suggestions, Thx in advance ;)
You could pass the URL to the fetchProducts function when dispatching actions on page changes.
handlePage(activePage) {
const url = `/api/v1/products/index/?page=${activePage}`
dispatch(fetchProducts(url))
}
And update the fetchProducts action creator to use the URL.
export function fetchProducts(url) {
return (dispatch) => {
dispatch(fetchProductsRequest())
axios
.get(url)
.then((response) => {
dispatch(fetchProductsSuccess(response.data.products))
})
.catch((error) => {
dispatch(fetchProductsFailure(error.message))
})
}
}
This is unrelated to the question but I would strongly recommend using React Query to simplify data fetching and synchronization.

Display data from state

I have took data from firebase and want to display:
class DisplayVisit extends Component{
state = {
allVisit: [] //this I have changed
}
componentDidMount(){
this.getVisit();
}
getVisit = async() => {
try {
const currentVisit = await doctorvisit.get();
this.setState({ allVisit: currentVisit })
this.state.allVisit.forEach(element => {
console.log(element.data()) // i see data, fields like => {user, info, visitAt}
});
} catch(error) {
console.log('error getting visits ', error);
}
}
render(){
return(
{Object.keys(this.state.allVisit).map(key => (
<span>{this.state.allVisit[key].info}1</span>
))}
)
}
}
But nothing is render.
I tried also {key.info} but nothing is render.
Screen from console:
Log from console.log(this.state.allVisit);:
If i see good, you're setting the state allVisit to currentVisit, wich is a single object.
Either your allVisit property in state is an array with visit objects inside, or simply apply currentVisit in state as a single object.
In the meantime, you're looping a single object, if its what you're trying to achieve, remove the .info after the [key] and you will have all you're property displayed
If you want to loop through nested objects or an array of object provide more informations
Update, i'll tried to guess your data so try with this code
export default class DisplayVisit extends Component {
state = {
allVisit: [] //this I have changed
};
componentDidMount() {
this.getVisit();
}
getVisit = async () => {
try {
const { docs } = await doctorvisit.get();
//try this if first not working
const allVisitsData = await doctor.visit.get()
this.setState({ allVisit: docs });
//try this if first not working
//this.setState({ allVisit: allVisitData.docs });
//or this
} catch (error) {
console.log("error getting visits ", error);
}
};
render() {
return (
<div>
{this.state.allVisit.map((visit) => (
<span key={visit.info}>{visit.info} 1</span>
))}
</div>
);
}
}
I did it based on Google docs:
class DisplayVisit extends Component{
state = {
allVisit: []
}
componentDidMount(){
this.getVisit();
}
getVisit = async() => {
try {
await doctorvisit.get().then(querySnapshot => {
const data = querySnapshot.docs.map(doc => doc.data());
this.setState({allVisit : data});
})
} catch(error) {
console.log('error getting visits ', error);
}
}
}
Documentation:
https://firebase.google.com/docs/firestore/query-data/get-data?hl=en
and blog/post:
https://rnfirebase.io/firestore/usage

React problems when i try to make an api call using fetch

i have a problem i try to make an api call to https://randomuser.me/api/ using fetch and i try to setstate my value array to the api data and then to map and i cant figure out where is the problem in my code because i get some errors
import "./App.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: [],
};
}
componentDidMount() {
fetch("https://randomuser.me/api/")
.then((res) => res.json())
.then((data) => this.setState({ value: data }));
}
render() {
return (
<div>
<p>test</p>
<div className="map">
{this.state.value.map((item) => (
<p>{item.gender}</p>
))}
</div>
</div>
);
}
}
export default App;
The endpoint you are fetching from sends the response as an object, when you try to setState with the call this.setState({ value: data }) it sets the entire response object as this.state.value. That is why you get the error "this.state.value.map is not a function" because this.state.value was replaced as an object by the setState call.
I believe you want the value of results property from the response object which has the correct array data for the user. You can simply change the setState call to set the value as data.results.
componentDidMount() {
fetch("https://randomuser.me/api/")
.then((res) => res.json())
.then((data) => this.setState({ value: data.results }));
}

ReactJS - Storing API data in state

New to React and JS in general so I apologize for the simplistic nature of this question.
I'm attempting to store a single child's name from my API in React's state but I must be doing something incorrectly with the JSON as this state is never updated.
If someone could explain what I'm doing incorrect and the best way to accomplish this, I'd very much appreciate it. My code almost mirrors this but I can't seem to figure out whats wrong here.
https://www.robinwieruch.de/react-fetching-data/
import React, { Component } from 'react';
import Child from '../../Components/Child/Child'
class MyKids extends Component {
constructor(props) {
super(props);
this.state = {
kidsName: '',
};
}
componentDidMount() {
fetch( 'http://localhost:3001/api/kids' )
.then( response => response.json())
.then(data => this.setState({kidsName: data[0].name}));
}
render() {
const { kidsName } = this.state;
return (
<div className = 'col-sm-12'>
<ul>
<p>{ kidsName }</p>
<Child
kidsName={ kidsName }
/>
</ul>
</div>
);
}
}
export default MyKids;
JSON Response:
{"success":true,"data":[{"_id":"5b10610c827ea427b05581b9","name":"Nick"},{"_id":"5b115bc8827ea427b05581bb","name":"Trevor"}]}
In your code the processing of the second then in the fetch should be:
componentDidMount() {
fetch( 'http://localhost:3001/api/kids' )
.then( response => response.json())
.then(data => this.setState({kidsName: data.data[0].name}));
}
For clarity you might change it for:
componentDidMount() {
fetch( 'http://localhost:3001/api/kids' )
.then( response => response.json())
.then(result => this.setState({kidsName: result.data[0].name}));
}
The mistake is here:
.then(data => this.setState({kidsName: data[0].name}));
This should be
.then(res => this.setState({kidsName: res.data[0].name}));
instead, because data in the first snippet has the shape { data: [...] }.

React doesn't render API data

Im building a recipe App and I got stuck and there is no error display or anything that can help me, Its my first time working with APIS in React and Im a little bit lost thats why im asking.
I´m trying to fetch data from this API and I don´t know why the properties will not show on the screen since I ve another example where it does.
I can see in the console with the React Developer extension that the properties are passed to the state so that´s fine and I dont understand why I cannot access or why it doesnt render.
In the other example doesn't get the data from an API it gets the data from a local object in json. Does it work different when it comes an API? Any idea?
import React, { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
this.state = {
recipes: []
};
}
componentDidMount() {
this.fetchData();
}
fetchData() {
fetch("https://www.themealdb.com/api/json/v1/1/random.php")
.then(response => response.json())
.then(json => {
this.setState({ recipes: json });
})
.catch(error => console.log("parsed error", error));
}
render() {
return <div className="box">{this.state.recipes.strMeal}</div>;
}
}
export default App;
Your code looks okay, but you need to render somehow your backend data:
fetchData() {
fetch("https://www.themealdb.com/api/json/v1/1/random.php")
.then(response => response.json())
.then(json => {
this.setState({ recipes: json.meals });
})
.catch(error => console.log("parsed error", error));
}
render() {
return (
<div className="box">
{this.state.recipes.map(m => <p>{m.strMeal}</p>)}
</div>
);
}
recipes is a json with meals key that is an array. Each element in the array has strMeal key (name of the meal).

Resources