this.props.history.push() not working in ReactJS - javascript

Trying my hands at ReactJS fetch() examples. As mentioned this.props.history.push() not working, it is not giving an error, but it is simply not redirecting. Tried to read other answers to this question on StackOverflow, but many of them are either too complex(some ppl showing off) or some not very clear.
index.js:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { BrowserRouter as Router, NavLink, Switch, Route, useHistory } from "react-router-dom";
import reportWebVitals from "./reportWebVitals";
ReactDOM.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>,
document.getElementById("root")
);
App.js :
import "./App.css";
import React from "react";
import { BrowserRouter as Router, NavLink, Switch, Route, useHistory } from "react-router-dom";
import RouterPage1 from "./RouterPage1";
import RouterPage2 from "./RouterPage2";
export default function App(props) {
let history = useHistory();
return (
<div>
<nav>
<ol>
<li>
<NavLink to="/RouterPage1">RouterPage1</NavLink>
</li>
<li>
<NavLink to="/RouterPage2">RouterPage2</NavLink>
</li>
<li>
<NavLink to="/RouterPageBoth">RouterPageBoth</NavLink>
</li>
</ol>
</nav>
<Switch>
<Route exact path="/RouterPage1">
<RouterPage1 history={history} />
</Route>
<Route exact path="/RouterPage2">
<RouterPage2 history={history} />
</Route>
</Switch>
</div>
);
}
RouterPage2.js(only the necessary code pasted, not the entire component for brevity):
addastakeholder = () => {
let newstakeholder = JSON.stringify(this.state.newstakeholder);
fetch("http://localhost:8080/OneToOneMappingPractice/add", {
method: "POST",
headers: { "Content-type": "application/json" },
body: newstakeholder,
}).then((r) => {
if (r.ok) {
//window.location.href = "/RouterPage2";
this.setState({ newstakeholder: { name: "", address: { house_number: "", streetName: "" } } });
this.props.history.push("/RouterPage2");
}
});
};
when I use the addastakeholder(), it is POSTing successfully, data is being entered in the DB, but it is not giving me an error and not redirecting. In the App.js, if I use the props and not useHistory(), it gives me "this.props.history not defined" error, even though I have enclosed App component in BrowserRouter component in the index.js.
Why is it so?
Secondly, if I use the commented out window.location.href = "/RouterPage2", it works(POSTing is successfull), but I am not able to see POST log in Development Tools:Network tab(Firefox). Why is this so?
Tried this.context.history.push("/RouterPage2"), does not work, same undefined error.
P.S.:edit 1:
the full RouterPage2.js(Kindly ignore result variable and the related code. Consider only result2.):
import React from "react";
export default class RouterPage2 extends React.Component {
constructor(props) {
super(props);
this.state = {
stakeholders: [],
errorString: "",
newstakeholder: { name: "", address: { house_number: "", streetName: "" } },
};
}
componentDidMount() {
fetch("http://localhost:8080/OneToOneMappingPractice/getAll")
.catch((error) => this.setState({ errorString: error }))
.then((result) => result.json())
.then((result) => this.setState({ stakeholders: result }));
}
addastakeholder = () => {
let newstakeholder = JSON.stringify(this.state.newstakeholder);
fetch("http://localhost:8080/OneToOneMappingPractice/add", {
method: "POST",
headers: { "Content-type": "application/json" },
body: newstakeholder,
}).then((r) => {
if (r.ok) {
//window.location.href = "/RouterPage2";
this.setState({ newstakeholder: { name: "", address: { house_number: "", streetName: "" } } });
this.props.history.push("/RouterPage2");
}
});
};
render() {
let result, result2;
let error = false;
if (this.state.stakeholders.length > 0)
result = (
<ol>
{this.state.stakeholders.map((stakeholder) => (
<li key={stakeholder.stakeholder_id}>
{stakeholder.stakeholder_name} | {stakeholder.stakeholder_type} |
{stakeholder.stakeholder_email_id} | {stakeholder.stakeholder_contactno} |
{stakeholder.stakeholder_bankname} | {stakeholder.stakeholder_bankBranch} |
{stakeholder.stakeholder_IFSC} | {stakeholder.stakeholder_AccNo} |
{stakeholder.stakeholder_AccType} | {stakeholder.stakeholder_PAN}
</li>
))}
</ol>
);
else result = false;
if (this.state.stakeholders.length > 0)
result2 = (
<ol>
{this.state.stakeholders.map((stakeholder) => (
<li key={stakeholder.id}>
{stakeholder.name}|{stakeholder.address.house_number}|{stakeholder.address.streetName}
</li>
))}
</ol>
);
else result2 = false;
if (this.state.errorString !== "undefined") error = this.state.errorString;
let blank = false;
if (result == false) blank = <h5>There are no records to display.</h5>;
return (
<div>
<h1>Stakeholder details :</h1>
{result2}
{error}
{blank}
<form>
Name :{" "}
<input
type="text"
placeholder="Name"
value={this.state.newstakeholder.name}
onChange={(e) => {
this.setState({ newstakeholder: { ...this.state.newstakeholder, name: e.target.value } });
}}
/>
<br></br>
StreetName :{" "}
<input
type="text"
placeholder="StreetName"
value={this.state.newstakeholder.address.streetName}
onChange={(e) => {
this.setState({
newstakeholder: {
...this.state.newstakeholder,
address: { ...this.state.newstakeholder.address, streetName: e.target.value },
},
});
}}
/>
<br></br>
HouseNumber :{" "}
<input
type="text"
placeholder="HouseNumber(Digits Only)"
value={this.state.newstakeholder.address.house_number}
onChange={(e) => {
this.setState({
newstakeholder: {
...this.state.newstakeholder,
address: { ...this.state.newstakeholder.address, house_number: e.target.value },
},
});
}}
/>
<br></br>
<button type="button" onClick={this.addastakeholder}>
Add Stakeholder
</button>
</form>
</div>
);
}
}

Tried everything. As suggested by Kurtis above in the comments, for troubleshooting purposes, did : console.log(this.props);
Got following response :
as you can see, there is the push function with different signature, hence tried : this.props.history.push("/RouterPage2", ""). Again did not work.
Hence, thought of trying the go(). And it worked.
this.props.history.go("/RouterPage2");
working now perfectly.

Related

The above error occurred in the <Provider> component

can't find way how to resolve this problem.
Errors in browser:
Uncaught Error: Invalid hook call. Hooks can only be called inside
of the body of a function component. This could happen for one of
the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to
debug and fix this problem.
The above error occurred in the component:
Provider#http://localhost:3000/static/js/bundle.js:49534:15
Consider adding an error boundary to your tree to customize error
handling behavior. Visit https://reactjs.org/link/error-boundaries
to learn more about error boundaries.
INDEX.JS
import React from 'react';
import ReactDOM from 'react-dom';
import Router from './Router';
import { createStore } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension'
import { Provider } from 'react-redux'
import rootReducer from './Redux/Reducers/index.js'
const store = createStore( rootReducer, composeWithDevTools() )
ReactDOM.render(
<Provider store={ store }>
<Router />
</Provider >,
document.getElementById( 'root' ) );
Reducers/index.js
import loginPageReducer from './LoginPage.js'
import { combineReducers } from 'redux'
const rootReducer = combineReducers( {
loginPageReducer
} )
export default rootReducer
Reducers/LoginPage.js
const INIT_STATE = {
view: 'login',
msg: '',
loader: false,
}
const loginPageReducer = ( state = INIT_STATE, action ) =>
{
switch ( action.type )
{
case "LOADER_OFF":
return state.loader = false
case "LOADER_ON":
return state.loader = true
case "MSG_SET":
return state.msg = action.msg
case "MSG_CLEAR":
return state.msg = ''
case "VIEW_CHANGE":
return state.view = action.view
default:
return state;
}
}
export default loginPageReducer
loginPage component
import React, { useState } from 'react'
import '../Styles/loginPage.scss'
import axios from 'axios'
import { useDispatch, useSelector } from 'react-redux'
import loginPageActions from '../Redux/actions/LoginPage'
export default function LoginPage ()
{
const { msg_clear, msg_set, loader_off, loader_on, view_change } = loginPageActions
const msg = useSelector( state => state.LoginPageReducer.msg )
const view = useSelector( state => state.LoginPageReducer.view )
const loader = useSelector( state => state.LoginPageReducer.loader )
const dispatch = useDispatch()
const [inputs, setInputs] = useState( {
username: '',
password: '',
password2: '',
email: ''
} )
const handleInputs = function ( e )
{
const { name, value } = e.target
setInputs( { ...inputs, [name]: value } )
}
const handleSubmit = async ( e ) =>
{
try
{
e.preventDefault();
dispatch( msg_clear() )
dispatch( loader_on() )
if ( view === login)
{
// logowanie
const query = await axios( {
method: 'post',
url: '/api/users/login',
data: {
username: inputs.username,
password: inputs.password
}
} )
const token = query.data.token
localStorage.setItem( "token", token );
return window.location.href = "/kalkulator"
}
else
{
//rejestracja
const query = await axios( {
method: 'post',
url: '/api/users/register',
data: {
username: inputs.username,
password: inputs.password,
password2: inputs.password2,
email: inputs.email
}
} )
if ( query.status === 200 )
{
dispatch( msg_set( 'Zarejestrowano, możesz się zalogować' ) )
dispatch( view_change( true ) )
}
}
}
catch ( err )
{
if ( err ) return dispatch( msg_set( err.response.data.msg ) )
}
finally
{
dispatch( loader_off() )
}
}
/////////////
/// Renderowanie widoku
/////////////
return (
<main>
<div id="MainContainerStyle">
<span id="thatWhitePartOnBottom"></span>
<header>
<h1 id="HeaderH1" >Kalkulator mas</h1>
</header>
<button className="Buttons" onClick={ () => dispatch( view_change( !view ) ) }>
{ view ?
`Already have account? Click to log in!`
:
`Doesn't have account? Click me if you want to register new one` }
</button>
<form onSubmit={ handleSubmit } id="Form">
<input type="text"
value={ inputs.username }
placeholder={ view ? 'username' : 'Login or E-mail' }
name="username" required onChange={ handleInputs }
/>
{ view ?
<input type="email"
placeholder="email"
name="email"
value={ inputs.email }
required
onChange={ handleInputs } />
:
null
}
<input type="password"
value={ inputs.password }
placeholder="Password:"
name="password"
required
onChange={ handleInputs }
/>
{ view ?
<input type="password"
value={ inputs.password2 }
placeholder="Password again:"
name="password2"
required
onChange={ handleInputs } />
:
null
}
<input type="submit" className="Buttons" />
{ loader ? <span className="loader"></span> : null }
{ msg !== '' ? <p className="msg">{ msg }</p> : null }
</form>
</div>
</main>
)
}
Router
import { BrowserRouter, Routes, Route } from "react-router-dom";
import './Styles/global.scss'
import LoginPage from "./Pages/LoginPage";
import Kalkulator from "./Pages/Kalkulator";
function App ()
{
return (
<>
<BrowserRouter>
<Routes>
<Route path="/" element={ <LoginPage /> } />
<Route path="/kalkulator" element={ <Kalkulator /> } />
</Routes>
</BrowserRouter>
</>
)
}
export default App;
might be this problem: https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react
Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.
..or maybe "react-redux" is not installed, check package.json

"No routes matched location"

I am developing a simple application of notes, and when I try to edit the notes, I get the error "No routes matched location id ..."
What am I doing wrong?
I try to get the id of the note by params
This is my code:
Notes.js:
import React from "react";
import Header from "./notes/Header";
import Home from "./notes/Home";
import CrearNota from "./notes/CrearNota";
import EditarNota from "./notes/EditarNota";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
export default function Notes({ setIsLogin }) {
return (
<header>
<BrowserRouter>
<Header setIsLogin={setIsLogin} />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/create" element={<CrearNota />} />
<Route path="/edit/:id" element={<EditarNota />} />
</Routes>
</BrowserRouter>
</header>
);
}
And EditarNotas.js:
import { useState, useEffect } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
export default function EditarNota(match) {
const [note, setNote] = useState({
title: "",
content: "",
date: "",
id: "",
});
const navigate = useNavigate();
useEffect(() => {
const getNote = async () => {
const token = localStorage.getItem("tokenStore");
if (match.params.id) {
const res = await axios.get(`/api/notes/${match.params.id}`, {
headers: { Authorization: token },
});
console.log(match.params.id);
console.log(res);
setNote({
title: res.data.title,
content: res.data.content,
date: res.data.date,
id: res.data._id,
});
}
};
getNote();
}, [match.params.id]);
const onChangeInput = (e) => {
const { name, value } = e.target;
setNote({ ...note, [name]: value });
};
const editNote = async (e) => {
e.preventDefault();
try {
const token = localStorage.getItem("tokenStore");
if (token) {
const { title, content, date, id } = note;
const newNote = {
title,
content,
date,
};
await axios.post(`api/notes/${id}`, newNote, {
headers: { Authorization: token },
});
return navigate.push("/");
}
} catch (err) {
window.location.href = "/";
}
};
return (
<>
<h2>Crear nota</h2>;
<form on onSubmit={editNote} autoComplete="off">
<div>
<label htmlFor="title">Title</label>
<input
type="text"
value={note.title}
id="title"
name="title"
required
onChange={onChangeInput}
/>
</div>
<div>
<label htmlFor="content">Content</label>
<input
type="text"
value={note.content}
id="content"
name="content"
required
rows="10"
onChange={onChangeInput}
/>
</div>
<div>
<label htmlFor="date">Date: {note.date}</label>
<input
type="date"
id="date"
name="date"
required
onChange={onChangeInput}
/>
</div>
<button type="submit">Guardar</button>
</form>
</>
);
}
It is my first post, if I have done something wrong, sorry and let me know.
Thanks in advance.
From your code it seems match is a props.
instead of accessing it like this:
export default function EditarNota(match)
try spreading the props like this:
export default function EditarNota({match})
or this way:export default function EditarNota(props)
then where ever you have match change it to props.match.
Instead of navigate.push('/'), navigate('/')

Not getting any data after form submission in ReactJS

After submitting my form I am not getting the submitted data on console and also the page is not routing
I am not getting the reason behind this. Searching for 2 days but still not got a suitable answer. Can anyone tell me the solution?
import axios from "axios";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
// import { createBrowserHistory as history } from "history";
import { withRouter } from "react-router-dom";
import DoneStatus from "./DoneStatus";
class Body extends React.Component {
titleDescMap = new Map();
constructor() {
super();
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChangeTitle = this.handleChangeTitle.bind(this);
this.handleChangeDescription = this.handleChangeDescription.bind(this);
this.handleCheckBoxChange = this.handleCheckBoxChange.bind(this);
}
state = {
countTodo: 1,
valueTitle: "",
valueDescription: "",
checkStatus: false,
routing: false,
};
statesStatus() {
return {
checkStatus: this.state.checkStatus,
};
}
handleChangeTitle(event) {
this.setState({
valueTitle: event.target.value,
});
}
handleChangeDescription(event) {
this.setState({
valueDescription: event.target.value,
});
}
handleCheckBoxChange(event) {
this.setState((prev) => ({ checkStatus: !prev.checkStatus }));
console.log(this.state.checkStatus);
}
handleSubmit(event) {
// Debugging my states
console.log("Id: " + this.state.id);
console.log("Title: " + this.state.valueTitle);
console.log("Description: " + this.state.valueDescription);
console.log("Check Status: " + this.state.checkStatus);
event.preventDefault();
var previousTitle = this.titleDescMap.has(this.state.valueTitle);
// Sending data to database
// Checking if any title and desc is previously stored
if (previousTitle) {
alert("Please Enter Another Title (which you have never used)");
} else {
// Setting the values in title and description into Map
this.titleDescMap.set(this.state.valueTitle, this.state.valueDescription);
console.log(this.titleDescMap);
// Updating id as counter increases 1
this.setState((previousState) => ({
countTodo: previousState.countTodo + 1,
}));
if (this.state.checkStatus) {
const backendData = {
countTodo: this.state.countTodo,
title: this.state.valueTitle,
description: this.state.valueDescription,
};
axios
.post("https://todo-list-site.herokuapp.com/todo-data", backendData)
.then((data) => {
console.log(data);
this.props.history.push("/submit");
})
.catch((err) => {
console.error("Error");
});
console.log(backendData);
}
}
}
render() {
console.log(this.state.checkStatus);
return (
<div className="body-container">
<p className="body-direction">Fill To Save Your Todo</p>
<form method="post" onSubmit={this.handleSubmit}>
<div className="form-group">
<label>Title</label>
<input
type="text"
className="form-control"
placeholder="Title here"
value={this.state.valueTitle}
onChange={this.handleChangeTitle}
/>
</div>
<div className="form-group">
<label>Description</label>
<br />
<textarea
className="form-control"
placeholder="Description here"
rows="4"
cols="40"
value={this.state.valueDescription}
onChange={this.handleChangeDescription}
/>
</div>
<div className="form-check">
<input
type="checkbox"
className="form-check-input"
onChange={this.handleCheckBoxChange}
/>
<label className="form-check-label body-input-label">
Save Permanently
</label>
</div>
<button
type="submit"
// onClick={() => history().push("/submit")}
className="btn btn-primary"
>
+ Add
</button>
</form>
</div>
);
}
}
export default withRouter(Body);
I have updated my code as per the given solution on this question. But still not getting the proper output
I want to send all the data in the form into my backend and render it on another page.
Data is submitting but I am not getting it on the console. Also routing is the major issue here.
I have added the file which includes all the routes
import Header from "./Header";
import Body from "./Body";
import DoneStatus from "./DoneStatus";
import Saved from "./Saved";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
// import Footer from "./Footer";
class App extends React.Component {
render() {
const body = new Body();
const checkStatus = body.statesStatus();
return (
<React.Fragment>
<Router>
<Header />
<Switch>
<Route
exact
path="/"
render={() => {
return (
<div className="app-container">
<Body />
</div>
);
}}
></Route>
</Switch>
<Switch>
<Route
exact
path="/saved"
render={() => {
return <Saved />;
}}
></Route>
</Switch>
{/* <Footer /> */}
<Switch>
<Route
exact
path="/submit"
render={() => {
return <DoneStatus checkedStatus={checkStatus.checkStatus} />;
}}
></Route>
</Switch>
</Router>
</React.Fragment>
);
}
}
export default App;
You are not waiting for your POST to finish, and as #Drew Reese points, you are calling the history wrong
handleSubmit(event) {
// Debugging my states
console.log("Id: " + this.state.id);
console.log("Title: " + this.state.valueTitle);
console.log("Description: " + this.state.valueDescription);
console.log("Check Status: " + this.state.checkStatus);
event.preventDefault();
var previousTitle = this.titleDescMap.has(this.state.valueTitle);
// Sending data to database
// Checking if any title and desc is previously stored
if (previousTitle) {
alert("Please Enter Another Title (which you have never used)");
} else {
// Setting the values in title and description into Map
this.titleDescMap.set(this.state.valueTitle, this.state.valueDescription);
console.log(this.titleDescMap);
// Updating id as counter increases 1
this.setState((previousState) => ({
countTodo: previousState.countTodo + 1,
}));
if (this.state.checkStatus) {
const backendData = {
countTodo: this.state.countTodo,
title: this.state.valueTitle,
description: this.state.valueDescription,
};
axios.post(
"https://todo-list-site.herokuapp.com/todo-data",
backendData
).then((response) => {
console.log(response);
history.push("/submit");
}).catch((error) => {
console.error(error);
});
}
}
}
Also, you are not waiting for the countTodo state to be setted after getting it to send it to the backend, that might get you unexpected behaviours some times
I think you are missing handling promise, please find below solution:
axios.get(`https://todo-list-site.herokuapp.com/todo-data`)
.then(backendData => {
console.log(backendData);
})

React Router changing URL, but component not rendering

I have been trying to learn React over the past couple of weeks and started working on a site which displays art works.
I would like for the user to be able to click on one of the images displayed and for a new component to be loaded with information about the work.
I have the implementation below of the gallery view, but when I click on an image the URL changes, but the WorkPage component never loads.
Would anyone be able to spot what I am doing wrong? The links and images are generated in the renderItems() function.
import React, { Component } from "react";
import Masonry from 'react-masonry-css';
import WorkPage from "./WorkPage"
import axios from "axios";
import { Link, Route, Switch, useRouteMatch, useParams } from "react-router-dom";
import { BrowserRouter as Router } from "react-router-dom";
class Works extends Component {
constructor(props) {
super(props);
this.state = {
viewPaintings: true,
workList: []
};
axios
.get("http://localhost:8000/api/works/")
.then(res => this.setState({ workList: res.data }))
.catch(err => console.log(err))
};
displayPaintings = status => {
if (status) {
return this.setState({ viewPaintings: true })
}
return this.setState({ viewPaintings: false })
};
renderTabList = () => {
return (
<div>
<ul className="tab-list-buttons">
<li onClick={() => this.displayPaintings(true)}
className={this.state.viewPaintings ? "active" : "disabled"}
key="button1"
>
Paintings
</li>
<li onClick={() => this.displayPaintings(false)}
className={this.state.viewPaintings ? "disabled" : "active"}
key="button2"
>
Works on Paper
</li>
</ul>
</div>
);
};
renderItems = () => {
const { viewPaintings } = this.state;
const newItems = viewPaintings
? this.state.workList.filter(item => item.type === 1)
: this.state.workList.filter(item => item.type === 0);
const breakpointColumnsObj = {
default: 4,
1100: 3,
700: 2,
500: 1
};
const items = newItems.map(item => (
<div key = {item.slug}>
<Link to={`${item.slug}`}>
<img src={item.image} alt={item.name} width="300"/>
</Link>
<Switch>
<Route path=":item.slug" component={WorkPage} />
</Switch>
</div>
));
return (
<Masonry
breakpointCols={breakpointColumnsObj}
className="my-masonry-grid"
columnClassName="my-masonry-grid_column"
>
{items}
</Masonry>
);
}
render() {
return (
<Router>
<div>
{ this.renderTabList() }
{ this.renderItems() }
</div>
</Router>
)
};
}
export default Works;

Unhandled Rejection (Error) in ReactJS, implementing files causes error

I'm trying to implement some search features for an online book store with reactjs. I found a good repo that uses the google book api and decided to implement it on my project to see how it would work. But I'm getting the following error:
enter image description here
my github is: https://github.com/luismir15/CEN4010.git branch: luis
//code implemented by jason rivera
import React, { Component } from 'react';
import BookList from './BookList';
import SearchBox from './SearchBox';
import request from 'superagent';
class Books extends Component {
constructor(props){
super(props)
this.state = {
books: [],
searchField: '',
sort: ''
}
}
componentDidMount() {
request
.get("https://www.googleapis.com/books/v1/volumes")
.query({ q: this.state.searchField })
.then((data) => {
this.setState({ books: [...data.body.items] })
})
}
handleSubmit = (e) => {
e.preventDefault();
request
.get("https://www.googleapis.com/books/v1/volumes")
.query({ q: this.state.searchField })
.then((data) => {
console.log(data);
this.setState({ books: [...data.body.items] })
})
}
handleChange = (e) => {
this.setState({ searchField: e.target.value })
}
handleSort = (e) => {
this.setState({ sort: e.target.value});
}
render() {
const filteredBooks = this.state.books.sort((a, b) => {
const price1 = a.saleInfo.hasOwnProperty('listPrice') == false ? "$0.00" : a.saleInfo.listPrice.amount;
const price2 = b.saleInfo.hasOwnProperty('listPrice') == false ? "$0.00" : b.saleInfo.listPrice.amount;
if(this.state.sort == 'Newest'){
console.log("in newest")
return parseInt(b.volumeInfo.publishedDate.substring(0, 4)) - parseInt(a.volumeInfo.publishedDate.substring(0, 4));
}
else if(this.state.sort == 'Oldest'){
return parseInt(a.volumeInfo.publishedDate.substring(0, 4)) - parseInt(b.volumeInfo.publishedDate.substring(0, 4));
}
else if(this.state.sort == 'High'){
return parseInt(b.volumeInfo.averageRating) - parseInt(a.volumeInfo.averageRating);
}
else if(this.state.sort == 'Low'){
return parseInt(a.volumeInfo.averageRating) - parseInt(b.volumeInfo.averageRating);
}
else if(this.state.sort === 'Expensive'){
return parseInt(price2) - parseInt(price1);
}
else if(this.state.sort === 'Cheap'){
return parseInt(price1) - parseInt(price2);
}
return;
})
return (
<div className="wrapper">
<SearchBox
data={this.state}
handleSubmit={this.handleSubmit}
handleChange={this.handleChange}
handleSort={this.handleSort}
/>
<BookList books={filteredBooks}/>
</div>
);
}
}
export default Books;
import React, { Component } from 'react';
import BookCard from './BookCard';
const BookList = (props) => {
return (
<div className="list">
{
props.books.map((book) => {
return <BookCard key={book.id} info={book} />
})
}
</div>
);
}
export default BookList;
import React, { Component } from 'react';
const SearchBox = (props) => {
return (
<div className="search-area">
<form onSubmit={props.handleSubmit}>
<input onChange={props.handleChange} placeholder="Search books" type="text"/>
<button type="submit">Search</button>
<select value={props.sort} onChange={props.handleSort}>
<option value="" disabled selected>Sort</option>
<option value="Newest">Newest</option>
<option value="Oldest">Oldest</option>
<option value="High">High to Low</option>
<option value="Low">Low to High</option>
<option value="Expensive">$$$-$</option>
<option value="Cheap">$-$$$</option>
</select>
</form>
</div>
);
}
export default SearchBox;
import React, { Component } from 'react';
const BookCard = (props) => {
const { volumeInfo } = props.info;
const { saleInfo } = props.info;
const {title, authors, averageRating, subtitle, publishedDate} = props.info.volumeInfo;
const price = saleInfo.hasOwnProperty('listPrice') == false ? "$0.00" : saleInfo.listPrice.amount;
const thumbNail = volumeInfo.hasOwnProperty('imageLinks') == false ? "https://vignette.wikia.nocookie.net/pandorahearts/images/a/ad/Not_available.jpg/revision/latest?cb=20141028171337" : volumeInfo.imageLinks.thumbnail;
const publishYear = volumeInfo.hasOwnProperty('publishedDate') == false ? volumeInfo['publishedDate'] = "0000" : volumeInfo.publishedDate;
return (
<div className="card-container">
<img src={thumbNail} alt=""/>
<div className="desc">
<h2>{title}</h2>
<p>Author: {authors}</p>
<p>Price: {price}</p>
<p>Raiting: {averageRating == "0.00" ? "Not available" : averageRating}</p>
<p>Published: {publishYear == "0000" ? "Not available" : publishYear.substring(0,4)}</p>
</div>
</div>
);
}
export default BookCard;
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import '../style/browsing.css';
import Books from '../component/Books';
const Home = () => {
return (
<div>
<ul className="flexbox-container">
<div className="browsing">
<Books/>
</div>
</ul>
</div>
);
}
export default Home;
import React from 'react';
import './index.css';
import './style/browsing.css';
import Home from './pages/Home';
import Register from './pages/Register';
import Login from './pages/Login';
import Orders from './pages/Orders';
import BookDetails from './pages/BookDetails';
import ShopCart from './pages/ShopCart';
import Profile from './pages/Profile';
//import Books from './component/Books';
import { Route, HashRouter, NavLink } from 'react-router-dom';
// NPM RUN CLIENT is the updated src folder, (NPM RUN SERVER/NPM START) runs build in my case which is the old green template
//Use ctrL + C to stop the server
//Always run NPM INSTALL on a newly cloned file
//Do not push updates to master branch, push to your own branch PLZ
//updated file structure on my branch (miguel) 2/17/20
//npm install after downloading/ npm install --save react-bootstrap mighe be needed for BookDetails to work
//npm npm run client to run this package
const App = () => (
<div>
<HashRouter>
<div>
<NavLink to="/" style={{ textDecoration: 'none' }}>
<h1><i class="material-icons">menu_book</i> GeekText</h1>
</NavLink>
<ul className="header">
<li><NavLink exact to="/">Home</NavLink></li>
<li><NavLink to="/Login">Login</NavLink></li>
<li><NavLink to="/Orders">Orders</NavLink></li>
<li><NavLink to="/BookDetails">Book Details</NavLink></li>
<li><NavLink to="/Profile">Profile</NavLink></li>
<li>
<NavLink to="/ShopCart">
<i class="material-icons md-dark md-24">shopping_cart</i>
</NavLink>
</li>
</ul>
<div className="content">
<Route exact path="/" component={Home} />
<Route path="/Register" component={Register} />
<Route path="/Login" component={Login} />
<Route path="/Orders" component={Orders} />
<Route path="/BookDetails" component={BookDetails} />
<Route path="/ShopCart" component={ShopCart} />
<Route path="/Profile" component={Profile} />
</div>
</div>
</HashRouter>
</div>
);
export default App;

Categories

Resources