So I have this Product.js component that fetches data from my backend data. I'm trying get this component to upload JSX code by using the data I fetched. However, when the server finishes my component just returns the div and not the data within it. Here's the code:
import React , {useState, useEffect} from 'react';
import { useParams } from 'react-router-dom';
import "./popup.css"
function Product(){
const [user, setUser] = useState();
const params = useParams()
console.log(params);
async function getUser(id) {
const response = await fetch(`http://localhost:8000/cats/${id}`)
const data = await response.json();
console.log(data);
setUser(params.id);
}
useEffect (() => {
getUser(params.id);
},[params.id])
document.body.style ='#bacdd8';
if(user){
return(
<div className='container'>
<div className='images'>
<img src={user.image_url} alt={user.name} />
</div>
<div className='cat'>
<h1>{user.name}</h1>
<p className='desc'>{user.description}</p>
</div>
</div>
)
}else{
<p>Still Loading...</p>
}
}
export default Product;
The code above shows what I've tried which was to just use an if statement to wait for the user to pick up something then return the JSX but apparently it doesn't in time. The only proof I have that it loads is when it shows on the console. However, my conclusion is that the JSX is just loading before the data. How can I fix this?
I think this is just a typo on your part. You should be setting the user to the data you got from the server and not the params id.
async function getUser(id) {
const response = await fetch(`http://localhost:8000/cats/${id}`)
const data = await response.json();
console.log(data);
setUser(params.id); <-----------------
}
Related
This is an API call and in console, i get all products . But when I use the same getProducts function in components I got undefined in console
export const getProducts = ()=> async(dispatch)=>{
try {
const data = await fetch("http://localhost:80/api/products/getallproducts",{
method:"GET",
headers:{
"Content-Type":"application/json"
}
});
const res = await data.json();
console.log(res);
dispatch({type:"SUCCESS_GET_PRODUCTS",payload:res});
} catch (error) {
dispatch({type:"FAIL_GET_PRODUCTS",payload:error.response});
}
}
I use it on Home page and got undefined instead of products as i am using same function of getProducts
import React, { useEffect } from 'react'
import Categories from '../components/Categories'
import Banner1 from '../components/Banner1'
import MaterialUiaresoul from '../components/MaterialUiaresoul'
import ProductSlide from '../components/ProductSlide'
import FeaturedProducts from '../components/FeaturedProducts'
import { useDispatch, useSelector } from 'react-redux'
import { getProducts } from '../redux/actions/action'
const Home = () => {
const products = useSelector(state => state.getproductsdata);
console.log(products)
const dispatch = useDispatch();
useEffect(() => {
dispatch(getProducts());
}, [dispatch]);
return (
<>
<MaterialUiaresoul/>
<ProductSlide/>
<Banner1/>
<Categories/>
<FeaturedProducts />
</>
)
}
export default Home
You are trying to dispatch something that is not redux action.
Let's see, you are trying to call this line dispatch(getProducts());
After getProduct call, it will return a new async function, that doesn't called and expect dispatch to be passed in it.
Normally actions look like this:
export function addTodo(text) {
return { type: ADD_TODO, text }
}
Its just a function that return a plain object with type as a required property.
When dealing with api calls using redux, its better to look into some libraries that will help you, such as redux-thunk or redux-saga for example. Redux actions sync by default and async behavior can be reached with use of some middlewares.
In your example, you can make your code work as expected if you will run your getProduct function, and then run response from it with dispatch passed as first argument:
const dispatch = useDispatch();
const createApiCall = getProduct();
createApiCall(dispatch)
I'm still not sure whether it will work and recommend you to look at redux-thunk. Its pretty easy to learn and use.
I have a component that fetch data from my MongoDB database.After fetching the data, I want to create some cards by this data. My backend server is working. Also I connect my frontend to backend.
import axios from "axios";
import Cards from "../components/Cards";
import CarouselComponent from "../components/Carousel";
import { Navbar } from "../components/Navbar";
export default function Home({ products }) {
console.log(products);
return (
<div className="">
<Navbar />
<CarouselComponent />
{/* <Cards products={products} /> */}
</div>
);
}
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`http://localhost:3000/api/products`);
const data = await res.json();
// Pass data to the page via props
return { props: { products: data } };
}
products prop is turns me empty object. But when I refresh the page second time, it brings me all the products. I tested it in postman, also in postman I can get all the products. Why when I stop the server and start it again it doesn't fetch the products?
SOLUTION
I added
await dbConnect();
to
export async function getServerSideProps() {
// Fetch data from external API
await dbConnect();
const res = await fetch(`http://localhost:3000/api/products`);
const data = await res.json();
// Pass data to the page via props
return { props: { products: data } };
}
I think my mistake was to try fetching data before connecting to server
Weather.JS File
import { useEffect, useState } from "react"
import axios from 'axios'
import WeatherDisplay from './WeatherDisplay'
const Weather = ({capital, params}) => {
const [weather,setWeather] = useState([])
useEffect(async () => {
const result = await axios.get('http://api.weatherstack.com/current', {params})
console.log(result.data)
setWeather(result.data)
},
[params])
return(
<div>
<h2>Weather in {capital}</h2>
<WeatherDisplay current={weather.current}/>
</div>
)
}
export default Weather
WeatherDisplay.js File
const WeatherDisplay = ({weather}) => {
console.log(weather.current.temperature)
return (
<h1>{weather.current.temperature}</h1>
)
}
export default WeatherDisplay
Having issues display the data when i use {weather.current.temperature}, it keeps giving me an error pointed at temperuture saying it isnt defined but its apart of the data
You are passing weather.current as props. While the child component is expecting weather as prop. So, what you end up doing is weather.current.current.temperature which is undefined because it doesn't exist. Just pass weather to the child prop.
Make this change when calling your child component.
<WeatherDisplay weather={weather}/>
I am new to react. I am following a video tutorials and get stuck at this point in request.js file.
This error occurred during the build time
./src/Row.js
Line 16:45: 'fetchUrl' is not defined no-undef
Search for the keywords to learn more about each error.
Row.js file
import Axios from 'axios';
import React, {useState, useEffect} from 'react';
import axios from './axios';
function Row({title}) {
// useState() is something where you can put your variable(dynamic) like arrays, objects, etc.
const [movies, setMovies] = useState([]) ;
// A snippet of code that runs on specific conditions/variable
useEffect(()=>{
// if [], run once when the row loads and don't run again.
// if [movies], it runs everytime when the movie changes. a row has lots of movies
async function fetchData(){
const request = await axios.get(fetchUrl) //await- wait for the promise to come.
console.log(request);
return request;
}
fetchData();
},[]);
return (
<div>
<h2>{title}</h2>
{/* container - poster */}
</div>
)
}
export default Row
axios.js
import axios from "axios";
// base url to make requests to the movie database
const instance = axios.create({
baseURL:"https://api.themoviedb.org/3",
})
export default instance;
App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Row from './Row';
import requests from './requests';
function App() {
return (
<div className="App">
<h1>Hey! Let's build the netflix app today</h1>
<Row title="NETFLIX Originals" fetchUrl={requests.fetchNetflixOriginals}></Row>
<Row title="Trending Now" fetchUrl={requests.fetchTrending}></Row>
</div>
);
}
export default App;
requests.js
const APIKey = "1cf5ee0bed7e36ed4b2a21b6ac834d55";
const requests = {
fetchTrending: `/trending/all/week?api_key=${APIKey}&language=en-US`,
fetchNetflixOriginals:`/discover/tv?api_key=${APIKey}&with_networks=213`,
fetchTopRated: `/movie/top_rated?api_key=${APIKey}&language=en-US`,
fetchActionMovies: `/discover/tv?api_key=${APIKey}&with_genres=28`,
fetchComedyMovies: `/discover/tv?api_key=${APIKey}&with_genres=35`,
fetchHorrorMovies: `/discover/tv?api_key=${APIKey}&with_genres=27`,
fetchRomanceMovies: `/discover/tv?api_key=${APIKey}&with_genres=10749`,
fetchDocumentaries: `/discover/tv?api_key=${APIKey}&with_genres=99`,
}
export default requests;
I am using this "fetchUrl" to send the request to App.js file but it says it is undefined.
It looks like fetchUrl is being passed via props:
function Row({title, fetchUrl}) {
// useState() is something where you can put your variable(dynamic) like arrays, objects, etc.
const [movies, setMovies] = useState([]) ;
// A snippet of code that runs on specific conditions/variable
useEffect(()=>{
// if [], run once when the row loads and don't run again.
// if [movies], it runs everytime when the movie changes. a row has lots of movies
async function fetchData(){
const request = await axios.get(fetchUrl) //await- wait for the promise to come.
console.log(request);
return request;
}
fetchData();
},[]);
return (
<div>
<h2>{title}</h2>
{/* container - poster */}
</div>
)
}
export default Row
Hopefully that helps!
fetchUrl is not defined because you forget to define it in the Row props. It should be:
function Row({title, fetchUrl}) { ... }
I am trying to render time data from API endpoint http://worldclockapi.com/api/json/utc/now
The "currentFileTime" property is constantly changing but renders once on load.
I tried setInterval method to update state but it doesn't work. May be I am making some mistake?
This is App.js:
import React , { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = { data: []};
}
async componentDidMount(){
this.fetchData();
}
async fetchData() {
try {
const response = await fetch('http://worldclockapi.com/api/json/utc/now');
if (!response.ok) {throw Error(response.statusText);}
const json = await response.json();
this.setState({ data: json});
console.log(json);
}
catch (error) {console.log(error);}
}
render() {return (<div><h1>worldclockapi.com data (edit App.js)</h1>
<li>currentFileTime: {this.state.data.currentFileTime }</li>
</div> );
}
}
export default App;
How to render and update currentFileTime continuously in react component?
the problem is componentDidMount executed only once, after component mounted for the first time, for example if your state changes componentDidMount is not gonna execute again.
in your case i think it's better to use websockets but if u wanna keep useing this api u can use useEffect hook like below:
const [temp, setTemp] = useState(0)
useEffect(()=>{
setIterval(()=>{
setTemp((prevTemp)=>prevTemp+1)
}, 2000)
}, [])
useEffect(()=>{
fetchData()
}, [temp])
in the above code we have a temp variable and it's value update every 2 second and every time it gets updated the second useEffect run and the data will fetch and as a result the state's gonna change and element gets updated.
Try Calling fecthData recursively upon successful data retrieval like below.
And you don't need to put "async" in front of componentDidMount cause you ain't awaiting anything in the method call.
async fetchData() {
try {
const response = await fetch('http://worldclockapi.com/api/json/utc/now');
if (!response.ok) {throw Error(response.statusText);}
const json = await response.json();
this.setState({ data: json});
console.log(json);
// set the time below to how frequently you wanna update
setTimeout(() => this.fetchData(), 5000);
//
}
catch (error) {console.log(error);}
}
This is using the new hooks. This should solve the problems
import React, {useEffect, useState} from 'react';
import logo from './logo.svg';
import './App.css';
const App = () => {
const [state, setState] = useState({data: []});
useEffect(()=>{
fetchData();
}, [state]);
const fetchData = async () => {
try {
const response = await fetch('http://worldclockapi.com/api/json/utc/now');
if (!response.ok) {throw Error(response.statusText);}
const json = await response.json();
setState({ data: json});
console.log(json);
}
catch (error) {console.log(error);}
}
return (<div><h1>worldclockapi.com data (edit App.js)</h1>
<li>currentFileTime: {state.data.currentFileTime }</li>
</div> );
}
export default App;