How to get id from json with axios get request - reactjs

I'm trying to get idrestaurant for use as identifier from json document that has info like this on json objects on the database. Stuff is on PostgreSQL
This is a react website for a school project. I have tried printing response.data on a console log but nothing shows.
[{"idrestaurant":2,
"name":"Pizzeria Amigo",
"address":"Uusikatu 16",
"opening":"08:00",
"closing":"12:00",
"img":"testi.com/kuva.jpg",
"type":"fastfood",
"pricelvl":"3",
"owneruserid":1},
{"idrestaurant":3,
"name":"Burgers",
"address":"Katu 10",
"opening":"08:00",
"closing":"18:00",
"img":"testi.com/kuva.png",
"type":"fastfood",
"pricelvl":"1",
"owneruserid":1}]
I want to use id as idrestaurant as unique key for printing list of restaurant elements at Restaurant.js. Here is what I have been trying to do.
App.js
import React, { useEffect, useState } from 'react'
import './App.css'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import NavBar from './components/navBar'
import Restaurants from './components/Restaurants'
import searchRestaurant from './components/Search'
import Restaurant from './components/Restaurant'
import axios from 'axios'
const App = () => {
const [restaurants, setRestaurants] = useState([])
useEffect(() => {
axios.get('http://MadeUpURL-app.herokuapp.com/restaurants')
.then((response) => {
setRestaurants(response.data)
});
}, []);
return (
<Router>
<div>
<NavBar />
<Routes>
<Route path='/restaurants' element={<Restaurants restaurants={restaurants} />} >
<Route path="/restaurants/idrestaurant" element={<Restaurant restaurants={restaurants} />} />
</Route>
{/* <Route path='/Search' element={<Search />} /> */}
</Routes>
</div>
</Router>
);
}
export default App
Restaurants.js
import React from 'react'
import styles from './restaurants.module.css'
import Restaurant from './Restaurant'
import { Link } from 'react-router-dom'
const Restaurants = (props) => {
return (
<div className={styles.container}>
<div className={styles.restaurantList}>
{props.restaurants.map(restaurant => <Link to={restaurant.idrestaurant}>
<Restaurant key={restaurant.idrestaurant} />
</Link>
)}
</div>
</div>
)
}
export default Restaurants
Restaurant.js
import React from 'react'
import styles from './restaurant.module.css'
export default function Restaurant(props) {
return (
<div className={styles.shop}>
<div>
<div><img src={props.img} className={styles.imageSize} /></div>
<div>
<div className={styles.title}>{props.name}</div>
<div className={styles.type}>{props.type}</div>
<div className={styles.prange}>{props.pricelvl}</div>
</div>
</div>
</div>
)
}

it is preferable to call api inside the Restaurants Component. Because setRestaurants will take time to update the state and in the mean time Restaurants Component will be render already so restaurants will be null in <Restaurants restaurants={restaurants} />
WORKING DEMO
Here is the code for App.js
import React, { useEffect, useState } from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Restaurants from "./components/Restaurants";
import Restaurant from "./components/Restaurant";
const App = () => {
return (
<Router>
<div>
<Routes>
<Route path="/" element={<Restaurants />} />
<Route path="/restaurants" element={<Restaurants />}>
<Route path="/restaurants/idrestaurant" element={<Restaurant />} />
</Route>
{/* <Route path='/Search' element={<Search />} /> */}
</Routes>
</div>
</Router>
);
};
export default App;
Here is the code for Restaurants.js
import React, { useEffect, useState } from "react";
import Restaurant from "./Restaurant";
import { Link } from "react-router-dom";
import axios from "axios";
const Restaurants = (props) => {
const [restaurants, setRestaurants] = useState([]);
const jsonFakeData = [
{
idrestaurant: 2,
name: "Pizzeria Amigo",
address: "Uusikatu 16",
opening: "08:00",
closing: "12:00",
img: "testi.com/kuva.jpg",
type: "fastfood",
pricelvl: "3",
owneruserid: 1
},
{
idrestaurant: 3,
name: "Burgers",
address: "Katu 10",
opening: "08:00",
closing: "18:00",
img: "testi.com/kuva.png",
type: "fastfood",
pricelvl: "1",
owneruserid: 1
}
];
useEffect(() => {
axios.get("https://jsonplaceholder.typicode.com/users").then((response) => {
console.log(response.data);
//setRestaurants(response.data);
setRestaurants(jsonFakeData);
});
}, []);
return (
<div>
<div>
{restaurants && restaurants.length > 0
? restaurants.map((restaurant) => (
<Link key={restaurant.idrestaurant} to={restaurant.idrestaurant}>
<Restaurant
restaurant={restaurant}
key={restaurant.idrestaurant}
/>
</Link>
))
: ""}
</div>
</div>
);
};
export default Restaurants;
Here is the code for Restaurant.js
import React from "react";
export default function Restaurant(props) {
console.log(props, "prps");
return (
<div>
<div>
<div>
<img src={props.restaurant.img} alt="img" />
</div>
<div>
<div>{props.restaurant.name}</div>
<div>{props.restaurant.type}</div>
<div>{props.restaurant.pricelvl}</div>
</div>
</div>
</div>
);
}

Related

I am calling a prop 2 times but it is working first time not working seond time

import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom';
import './Allproducts.css'
import Categories from './categories.json'
import ForYouItem from './ForYouItem'
export default function Allproducts(props) {
const [products, setProducts] = useState([]);
useEffect(() => {
fetch(`https://fakestoreapi.com/products/category/${props.category}`)
.then((res) => res.json())
.then((data) => setProducts(data))
}, [])
return (
<>
<div className="banner">
<h1>All Products</h1>
<h4>Get best items in budget</h4>
</div>
<div className="main-grid">
<div className="left-grid">
<div className="left-categories">
<h1>Collections</h1>
{Categories.map((category) => {
let Afeef = `/${props.category}`
return (
<Link to= {Afeef} className='products-categories'> <h4>{category.title}</h4></Link>
)
}
)}
</div>
</div>
<div className="right-grid">
<div className="row ">
{products.map((product) => {
return (
<div className="col-md-4 my-2 Products-1">
<ForYouItem Title={product.title.slice(0, 50)} Price={product.price} Imageurl={product.image} rate={product.rating.rate} count={product.rating.count} />
</div>
)
}
)}
</div>
</div>
</div>
</>
)
}
So in this code I am calling same prop two times, first in this line;
fetch(https://fakestoreapi.com/products/category/${props.category})
Secondly here;
let Afeef = /${props.category}
The prop is working in the First line but on the second line it gives no result. The link isn't changed.
What I want is when I click on second Link I get redirected "/${props.category}" but the URL is not changing
Code for App.js:
import React, { Component } from 'react'
import './App.css';
import NavBar from './components/NavBar';
import TopBar from './components/TopBar'
import {
HashRouter,
Routes,
Route,
} from "react-router-dom";
import Mainpage from './Mainpage';
import Login from './components/Login';
import Signup from './components/Signup';
import Allproducts from './components/Allproducts';
function App() {
return (
<div>
<HashRouter>
<TopBar/>
<NavBar/>
<Routes>
<Route path="/" element={<Mainpage/>}></Route>
<Route path="/Login" element={<Login/>}></Route>
<Route path="/Signup" element={<Signup/>}></Route>
<Route path="/jewelery" element={<Allproducts category="jewelery"/>}></Route>
<Route path="/electronics" element={<Allproducts category="electronics"/>}></Route>
<Route path="/men's clothing" element={<Allproducts category="men's clothing"/>}></Route>
<Route path="/women's clothing" element={<Allproducts category="women's clothing"/>}></Route>
</Routes>
</HashRouter>
</div>
);
}
export default App;

ReferenceError: Worker is not defined while testing AppRouter Component

I am testing a React/Typescript component using Jest and React Testing-Library. I am doing a simple render test and getting a Reference Error: Worker is not defined.
Why and how would I use a worker in this testing context?
Here is my simple test:
import {render, screen} from '#testing-library/react'
import userEvent from '#testing-library/user-event'
import React from 'react'
import {Router} from 'react-router-dom'
import AppRouter from '../router'
test('AppRouter renders all routes and I can navigate to those pages', () => {
render(<AppRouter />)
screen.debug()
})
And here is the AppRouter component:
import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom'
import { useState } from 'react'
import useLocalStorage from './hooks/useLocalStorage'
import * as Constants from './constants'
import Header from './layout/header/header'
import MainPage from './pages/mainPage/mainPage'
import PostPage from './pages/postPage/postPage'
import UserPage from './pages/userPage/userPage'
import LoginPage from './pages/loginPage/loginPage'
import SignupPage from './pages/signupPage/signupPage'
import NewPage from './pages/newPage/newPage'
import FeedbackPage from './pages/feedbackPage/feedbackPage'
import AdminPage from './pages/adminPage/adminPage'
import SettingPage from './pages/settingPage/settingPage'
import { WebContext } from './context/WebContext'
import Favicon from 'react-favicon'
const AppRouter = () => {
const [adminCode, setAdminCode] = useLocalStorage('admin', '')
const [isMenuOpen, setIsMenuOpen] = useState(false)
const [page, setPage] = useState(Constants.Page.Home)
return (
<BrowserRouter>
<div>
<Favicon url={require('../public/favicon.ico')} />
<WebContext.Provider
value={{
isMenuOpen,
setIsMenuOpen,
page,
setPage,
adminCode,
setAdminCode,
}}
>
<Header />
<Switch>
<Route component={MainPage} path="/" exact={true} />
<Route component={PostPage} path="/post/:id" />
<Route component={UserPage} path="/user" />
<Route component={LoginPage} path="/login" />
<Route component={SignupPage} path="/signup" />
<Route component={NewPage} path="/new" />
<Route component={FeedbackPage} path="/feedback" />
<Route component={AdminPage} path="/admin" />
<Route component={SettingPage} path="/setting" />
<Route component={() => <Redirect to="/" />} />
</Switch>
</WebContext.Provider>
</div>
</BrowserRouter>
)
}
export default AppRouter
Most of what I researched on this were old Jest stackoverflows. I am aware there is a jest-worker package but not sure why I would need this or how I would use it when running this simple test.
Here is a link to jest-worker.
Code Trace:
Header component
import { useContext, useState } from 'react'
import { NavLink, useHistory, useLocation } from 'react-router-dom'
import { observer } from 'mobx-react-lite'
import { WebContext } from '../../context/WebContext'
import UnirepContext from '../../context/Unirep'
import UserContext from '../../context/User'
const Header = () => {
const history = useHistory()
const location = useLocation()
const { isMenuOpen, setIsMenuOpen } = useContext(WebContext)
const [searchInput, setSearchInput] = useState<string>('')
const unirepConfig = useContext(UnirepContext)
const userContext = useContext(UserContext)
const gotoNewPage = () => {
if (
userContext.userState &&
userContext.netReputation >= unirepConfig.postReputation
) {
history.push(`/new`, { isConfirmed: true })
}
}
const gotoUserPage = () => {
history.push(`/user`, { isConfirmed: true })
}
const openMenu = () => {
if (!isMenuOpen) {
console.log('open menu!')
setIsMenuOpen(true)
}
}
const handleSearchInput = (event: any) => {
console.log('search input : ' + event.target.value)
}
return (
<header>
<div className="navLinks">
<NavLink to="/" className="link" activeClassName="active" exact>
<img
src={require('../../../public/images/unirep-title.svg')}
/>
</NavLink>
</div>
{/* <div className="search-bar">
<div className="search-icon"><FaSearch /></div>
<form>
<input type="text" name="searchInput" placeholder="Search by keyword, user names or epoch key" onChange={handleSearchInput} />
</form>
</div> */}
{userContext.userState ? (
<div className="navButtons">
<div id="rep" onClick={gotoUserPage}>
<img
src={require('../../../public/images/lighting.svg')}
/>
{userContext.netReputation}
</div>
<div
id="new"
className={
location.pathname === '/new'
? 'navBtn chosen'
: 'navBtn'
}
>
<img
src={require('../../../public/images/newpost.svg')}
onClick={gotoNewPage}
/>
</div>
<div
id="user"
className={
location.pathname === '/user'
? 'navBtn chosen'
: 'navBtn'
}
>
<img
src={require('../../../public/images/user.svg')}
onClick={gotoUserPage}
/>
</div>
<div className="navBtn">
<img
src={require('../../../public/images/menu.svg')}
onClick={openMenu}
/>
</div>
</div>
) : (
<div className="navButtons">
<div
id="login"
className="whiteButton"
onClick={() => history.push('/login')}
>
Sign in
</div>
<div
id="join"
className="blackButton"
onClick={() => history.push('/signup')}
>
Join
</div>
<div id="menu" className="navBtn">
<img
src={require('../../../public/images/menu.svg')}
onClick={openMenu}
/>
</div>
</div>
)}
</header>
)
}
export default observer(Header)
EDIT
The problem may stem from using MobX for state management and not wrapping the component in a Provider but still unsure of how to do this.

proxy not always working : axios error 404

I have a problem with my proxy. When I am in the homepage, the proxy is working but when I go to another page (using Link from react-router-dom) it's not taken into account.
I have the error: Object { message: "Request failed with status code 404", name: "AxiosError", code: "ERR_BAD_REQUEST"..}
and the http request is : http://localhost:3000/profile/posts/profile/olive
but I want it to be : http://localhost:8800/api/profile/olive
In package.json I have : "proxy": "http://localhost:8800/api/"
And here are the scripts that I use (Feed.jsx):
import "./feed.css";
import Share from "../share/Share";
import Post from "../post/Post";
import { useState, useEffect } from "react";
import axios from "axios"
export default function Feed({ username }) {
const [posts, setPosts] = useState([]);
useEffect(() => {
const fetchPosts = async () => {
const res = username
? await axios.get("posts/profile/" + username)
: await axios.get("posts/timeline/629f61ef4ed27a5d39094ced");
setPosts(res.data)
};
fetchPosts();
}, []);
return (
<div className="feed">
<div className="feedWrapper">
<Share />
{posts.map((p) => (
<Post key={p._id} post={p} />
))}
</div>
</div>
)}
This is my App.js:
import {
BrowserRouter as Router,
Routes as Switch,
Route,
} from "react-router-dom";
import Homepage from "./pages/homepage/Homepage";
import Login from "./pages/login/Login"
import Register from "./pages/register/Register"
import Profile from "./pages/profile/Profile"
function App() {
return (
<>
<Router>
<Switch>
<Route exact path="/" element={<Homepage/> }/>
<Route exact path="/login" element={<Login/> }/>
<Route exact path="/register" element={<Register/> }/>
<Route path="/profile/:username" element={<Profile/> }/>
</Switch>
</Router>
</>
);
}
export default App;
This is my Profile.jsx:
import "./profile.css"
import Topbar from "../../components/topbar/Topbar";
import Sidebar from "../../components/sidebar/Sidebar";
import Feed from "../../components/feed/Feed";
import Rightbar from "../../components/rightbar/Rightbar";
export default function Profile() {
const PF=process.env.REACT_APP_PUBLIC_FOLDER;
return(
<>
<Topbar/>
<div className="profile">
<Sidebar/>
<div className="profileRight">
<div className="profileRightTop">
<div className="profileCover">
<img src={`${PF}post/3.jpeg`} alt="" className="profileCoverImage" />
<img src={`${PF}person/5.jpeg`} alt="" className="profileUserImage" />
</div>
<div className="profileInfo">
<h4 className="profileInfoName">Louise Dupuis</h4>
<span className="profileInfoDesc">Hello everyone I am a spiritual coach</span>
</div>
</div>
<div className="profileRightBottom">
<Feed username="olive"/>
<Rightbar profile/>
</div>
</div>
</div>
</>
);
}
And this is how I linked a button from the homepage to the profile page.
<Link to={`/profile/${user.username}`}>
<img className="postProfileImage" src={user.profilePicture || PF+"person/no_avatar.png"} alt="" />
</Link>
Thank you in advance for your attention and your help. I really tried and searched but I didn't find. I don't know what's wrong in my code ...

How to get parameters through component on react-router-dom-6

I am new to React JS. I am learning react router dom version 6. I am having an problem. I am not getting parameters through components.
Here is my codes:
App.js
import React, { Component } from 'react';
import './App.css';
import Movies from './components/movies';
import Customers from './components/customers';
import Rentals from './components/rentals';
import NotFound from './components/not-found';
import Navbar from './components/navbar';
import MovieForm from './components/movieform'
import { Route, Routes, Navigate } from 'react-router-dom';
class App extends Component {
render() {
return (
<main>
<Navbar />
<Routes>
<Route path='/movies/:id' element={<MovieForm />} />
<Route path="/" element={<Navigate replace to="/movies" />} />
<Route path="/movies" element={<Movies />} />
<Route path="/customers" element={<Customers />} />
<Route path="/Rentals" element={<Rentals />} />
<Route path="*" element={<NotFound />} />
</Routes>
</main>
);
}
}
export default App;
moviesform.jsx
import React from 'react';
const MovieForm = props => {
console.log(props);
return (
<div className="container">
<h1>Movie Form </h1>
</div>
)
}
export default MovieForm;
I get this through React Developer Tools extension:
{
"children": "<MovieForm />",
"value": {
"outlet": null,
"matches": [
{
"params": "{id: \"5b21ca3eeb7f6fbccd471816\"}",
"pathname": "/movies/5b21ca3eeb7f6fbccd471816",
"pathnameBase": "/movies/5b21ca3eeb7f6fbccd471816",
"route": "{caseSensitive: undefined, element: <MovieForm />, …}"
}
]
}
}
How can I access the parameters?
You can use useParams to access params in react-router-dom v6
import React from 'react';
import { useParams } from 'react-router-dom';
const MovieForm = () => {
const params = useParams();
console.log(params);
return (
<div className="container">
<h1>Movie Form </h1>
</div>
)
}
export default MovieForm;
You can use the hook that react-router-dom provides called useParams
So to access your id parameter you'll have to go into your MovieForm component and use it there
import { useParams } from 'react-router-dom';
const MovieForm = props => {
const { id } = useParams();
console.log(props);
return (
<div className="container">
<h1>Movie Form </h1>
</div>
)
}

Cannot read property 'isLoggedIn' of null

Hi all I am currently stuck with the following:
Cannot read property 'isLoggedIn' of null
> 9 | const Header = () => {
10 | const {isLoggedIn} = useContext(AuthContext);
11 | return (
12 | <ul className="nav">
I am new in React and I was following a tutorial to implement a sign-in/sign-up form and sending data to firebase (which is also something completely new to me). I was able to fix a couple of previous issues on my own but I am now stuck at this one.
If I don't import the Header into the Routing the site works fine but as soon as I try to import it in any way to Routing.js it's failing.
Header.js
import React, { useContext } from "react";
import routes from "./routes";
import { Link } from "react-router-dom";
import { AuthContext } from "./test";
const Header = () => {
const {isLoggedIn} = useContext(AuthContext);
return (
<ul className="nav">
{routes.map((route, i) => (
<li key={i}>
<Link to={route.path}>{route.name}</Link>
</li>
))}
{isLoggedIn && <li><Link to="/reports">Profile</Link></li>}
</ul>
)
}
export default Header;
Routing.js
import React from "react";
import Head from "./Head";
import Join from "./Join";
import Login from "./Login";
import Test from "./test";
import HomePage from "./HomePage";
import Header from "./Header";
import { BrowserRouter as Router, Switch, Route, Link} from "react-router-dom";
function Home() {
return (
<div className="App">
<Head />
<HomePage />
</div>
);
}
function Reviews() {
return (
<div className="App">
<Head />
</div>
);
}
function Logging() {
return (
<div className="App">
<Head />
<Header />
<Test />
</div>
);
}
function Signup() {
return (
<div className="App">
<Head />
<Header />
<Test />
</div>
);
}
function App() {
return (
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/review" exact component={Reviews} />
<Route path="/login" exact component={Logging} />
<Route path="/signup" exact component={Signup} />
</Switch>
</Router>
)
}
export default App;
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { Switch, BrowserRouter as Router, Route } from "react-router-dom";
import routes from "./routes.js";
import Header from "./Header";
import "./styles.css";
import * as firebase from "firebase";
import firebaseConfig from "./firebase.config";
import protectedRoutes from './protectedRoutes'
import ProtectedRouteHoc from './ProtectedRouteHoc'
firebase.initializeApp(firebaseConfig);
export const AuthContext = React.createContext(null);
function Test() {
const [isLoggedIn, setLoggedIn] = useState(false);
function readSession() {
const user = window.sessionStorage.getItem(
`firebase:authUser:${firebaseConfig.apiKey}:[DEFAULT]`
);
if (user) setLoggedIn(true)
}
useEffect(() => {
readSession()
}, [])
return (
<AuthContext.Provider value={{ isLoggedIn, setLoggedIn }}>
Is logged in? {JSON.stringify(isLoggedIn)}
<div className="App">
<Router>
<Header isLoggedIn={isLoggedIn}/>
<Switch>
{protectedRoutes.map(route => (
<ProtectedRouteHoc
key={route.path}
isLoggedIn={isLoggedIn}
path={route.path}
component={route.main}
exact={route.exact}
public={route.public}
/>
))}
{routes.map(route => (
<Route
key={route.path}
path={route.path}
exact={route.exact}
component={route.main}
/>
))}
</Switch>
</Router>
</div>
</AuthContext.Provider>
);
}
export default Test;
I would appreciate any tips or things I can read through to get a better understanding in this.
You're destructing the return value of useContext(AuthContext). You're expecting it to return an object with a key isLoggedIn, e.g. { isLoggedIn: false }, but it's returning null instead. You probably haven't given it a default value when you instantiated the context instance, e.g.
// Possibly what you're doing, no default value
const AuthContext = React.createContext() // null
// Instantiated with a default value
const AuthContext = React.createContext({ isLoggedIn: false })

Resources