I am trying to connect my react app to firebase, it was working perfectly befor connecting it to firebase, now I am getting this error:
Clients
src/components/clients/Clients.js:16:8
if (clients) {
return (
<div>
<div className="row">
<div className="col-md-6">
<h2>
here is my Clients.js code :
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { compose } from "redux";
import { connect } from "react-redux";
import { firestoreConnect } from "react-redux-firebase";
import PropTypes from "prop-types";
class Clients extends Component {
render() {
const clients = this.props.clients;
if (clients) {
return (
<div>
<div className="row">
<div className="col-md-6">
<h2>
{" "}
<i className="fas fa-users" /> Clients{" "}
</h2>
</div>
<div className="col-md-6">---</div>
</div>
<table className="table table-striped">
<thead className="thead-inverse">
<tr>
<th>Name</th>
<th>Email</th>
<th>Balance</th>
<th />
</tr>
</thead>
<tbody>
{clients.map(client => (
<tr key={client.id}>
<td>
{client.firstName} {client.lastName}
</td>
<td>{client.email}</td>
<td>${parseFloat(client.balance).toFixed(2)}</td>
<td>
<Link
to={`/client/${client.id}`}
className="btn btn-secondary btn-sm"
>
<i className="fas fa-arrow-circle-right" /> Details
</Link>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
} else {
return <h1>Loading</h1>;
}
}
}
Clients.prototype = {
firestore: PropTypes.object.isRequired,
clients: PropTypes.array
};
export default compose(
firestoreConnect([{ collection: "clients" }]),
connect((state, props) => ({
clients: state.firestore.ordered.clients
}))
)(Clients);
How can i solve that problem ? it's first time for me to try fire base.
I am using "react-redux" version 5.1.1 and "react-redux-firebase" version 2.2.4.
You seems to use react-router.
In your router .js file, change this:
<Route path="/" render={Clients} />
To this:
<Route path="/" component={Clients} />
Another fix would be to sadly avoid "compose" by doing this:
connect(
(state, props) => ({
clients: state.firestore.ordered.clients
})
)(
firestoreConnect([{ collection: "clients" }])(Clients)
);
I've fixed the problem by changing these lines :
First I changed:
const clients = this.props.clients;
To :
const { clients } = this.props;
Then I changed :
Clients.prototype = {
firestore: PropTypes.object.isRequired,
clients: PropTypes.array
};
To :
Clients.propTypes = {
firestore: PropTypes.object.isRequired,
clients: PropTypes.array
};
and now it is working perfectly
Related
Data doesn't seem to be showing in my table for a Axios API call within react believe the error is related to this console error below.
Following a YT tutorial https://www.youtube.com/watch?v=AcYhi08e404
Cannot Read properties of undefined (Reading 'map')]
APP.JS
import React, { useEffect, useState } from 'react';
import { Route, Routes } from 'react-router-dom';
import Navbar from './components/Navbar';
import { ThemeProvider } from './context/ThemeContext';
import Home from './pages/Home';
import Signin from './pages/Signin';
import Signup from './pages/Signup';
import Account from './pages/Account';
import axios from 'axios';
function App() {
const [coins, setCoins] = useState([]);
useEffect(() => {
axios.get(
'https://api.coingecko.com/api/v3/coins/markets?vs_currency=gbp&order=market_cap_desc&per_page=10&page=1&sparkline=true'
)
.then(res => {
setCoins(res.data);
console.log(res.data);
})
.catch(error => console.log(error));
}, []);
return <ThemeProvider>
<Navbar />
<Routes>
<Route path='/' element={<Home coins={coins} />} />
<Route path='/signin' element={<Signin />} />
<Route path='/signup' element={<Signup />} />
<Route path='/account' element={<Account />} />
</Routes>
</ThemeProvider>;
}
export default App;
COINSEARCH.JSX
import React from 'react';
import CoinItem from './CoinItem';
const CoinSearch = ({ coins }) => {
return (
<div>
<div>
<h1>Search</h1>
<form>
<input type="text" placeholder='Search'/>
</form>
</div>
<table className='w-full border-collapse text-center'>
<thead>
<tr className='border-b'>
<th></th>
<th className='px-4'>#</th>
<th className='text-left'>Coin</th>
<th></th>
<th>Price</th>
<th>24h</th>
<th className='hidden md:table-cell'>24h Volume</th>
<th className='hidden sm:table-cell'>Mkt</th>
<th>Last 7 Days</th>
</tr>
</thead>
<tbody>
<tr>
{coins.map((coin) => (
<CoinItem key={coin.id} coin={coin} />
))}
</tr>
</tbody>
</table>
</div>
);
};
export default CoinSearch;
COINITEM.JSX
import React from 'react'
import { AiOutlineStar } from 'react-icons/ai'
import { Sparklines, SparklinesLines } from 'react-sparklines';
export const CoinItem = ({coin}) => {
return (
<tr>
<td>
<AiOutlineStar />
</td>
<td>{coin.market_cap_rank}</td>
<td>
<div>
<img src={coin.image} alt={coin.id} />
<p>{coin.name}</p>
</div>
</td>
<td>{coin.symbol}</td>
<td>{coin.current_price}</td>
<td>{coin.price_change_percentage_24h}</td>
<td>{coin.total_volume}</td>
<td>{coin.market_cap}</td>
<td>
<Sparklines data={coin.sparkline_in_7d.price}>
<SparklinesLines color='green' />
</Sparklines>
</td>
</tr>
);
};
export default CoinItem;
Reasonably new to react and struggling to get past this hurdle, any help would be appreciated!
In Initial render, coin is undefined until it fetches the data , so use shortcircuit condition in COIN component
<tbody>
<tr>
// map through coins only if its defined..
{coins && coins.map((coin) => (
<CoinItem key={coin.id} coin={coin} />
))}
</tr>
</tbody>
you are sending props to your home component in App.js can you show me your home component
The problem is data is not reaching CoinSearch component because in home component you are not getting props. your code for home component will be this.
import React from 'react'
import CoinSearch from '../components/CoinSearch'
export const Home = ({coins}) => {
return (
<div>
<CoinSearch coins = {coins} />
</div>
)
}
export default Home;
try this piece of code in home component hopefully it will work.
This question already has an answer here:
Problem in redirecting programmatically to a route in react router v6
(1 answer)
Closed last year.
I'm completely new to react and got stuck on the following 'route' part.
Here is the code:
This is my ListEmployeeComponent :
import React, { Component } from 'react';
import EmployeeService from '../services/EmployeeService';
class ListEmployeesComponent extends Component {
constructor(props) {
super(props);
this.state = {
employees: []
}
this.addEmployee = this.addEmployee.bind(this);
}
componentDidMount() {
EmployeeService.getEmployees().then((res) => {
this.setState({employees: res.data});
});
}
addEmployee() {
this.props.history.push('add-employee');
}
render() {
return (
<div>
<h2 className="text-center">Employee List</h2>
<div className="row">
<button className="btn btn-primary" onClick={this.addEmployee}>Add Employee</button>
</div>
<div className="row">
<table className="table table-striped table-bordered">
<thead>
<tr>
<th>Id</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email Id</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{
this.state.employees.map(
employee =>
<tr key={employee.id}>
<td>{employee.id}</td>
<td>{employee.firstName}</td>
<td>{employee.lastName}</td>
<td>{employee.email}</td>
</tr>
)
}
</tbody>
</table>
</div>
</div>
);
}
}
export default ListEmployeesComponent;
And this is my App.js :
import './App.css';
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom'
import FooterComponent from './components/FooterComponent';
import HeaderComponent from './components/HeaderComponent';
import ListEmployeesComponent from './components/ListEmployeesComponent';
import CreateEmployeeComponent from './components/CreateEmployeeComponent';
function App() {
return (
<div>
<Router>
<HeaderComponent/>
<div className="container">
<Routes>
<Route path="/" element={<ListEmployeesComponent/>}></Route>
<Route path="/home" element={<ListEmployeesComponent/>}></Route>
<Route path="/add-employee" element={<CreateEmployeeComponent/>}></Route>
</Routes>
</div>
<FooterComponent/>
</Router>
</div>
)
}
export default App;
My issue is that I want to route to CreateEmployeeComponent when the button gets clicked, but there is no action happening when I click the button. I tried checking the new documentation for react-router v6 but it wasn't much help.
What can I do differently here to resolve my issue?
Solution 1:
You can wrap the button in ListEmployeeComponent using Link from react-router-dom.
<Link to="/add-employee">
<button className="btn btn-primary">Add Employee</button>
</Link>
reference: react-router-dom
Solution 2:
history in react-router-dom v6 has been replaced by Navigate. So if you want to push /add-employee to history you need to use
<Navigate to='/add-employee' push={true}/>
Make following changes in your ListEmployeeComponent.js :
add a state in your constructor:
constructor(props) {
super(props);
this.state = {
navigate: false,
employees: []
}
this.addEmployee = this.addEmployee.bind(this);
}
change your function:
addEmployee() {
this.props.history.push('add-employee');
}
to
addEmployee() {
this.setState({
navigate: true,
});
}
and change your render method to:
render() {
const { navigate } = this.state;
if (navigate) {
return <Navigate to="/add-employee" push={true} />;
}
return (
<div>
<h2 className="text-center">Employee List</h2>
<div className="row">
........
//rest of the code
}
reference: react-router-dom-v6 doc
First you have to import link in ListEmployeeComponent
and
have to use button tags between link tags
and you have to add [to="/add-employee"] attributes to link tag
import {Link} from "react-router-dom";
<Link to="/add-employee">
<button
className="btn btn-primary"
onClick={this.addEmployee}
>
Add Employee
</button>
</Link>
I want to render large lists of data inside a table. I am using the React-List library found online, but when the user scrolls about 200 items, the rest of them take too much time to load.
I achieved something like this:
After about 200 items, I get these warnings in the console, and the list starts to render slower and slower like in the image below:
I use React-List for rendering this table and a get request to get all the data once, code will be shown below.
import React from 'react';
import axios from 'axios';
import { toastr } from '../../../components/toastr/toastr.component';
import { Table } from 'react-bootstrap';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faTrashAlt } from '#fortawesome/free-solid-svg-icons';
import DaysJS from 'react-dayjs';
import Loading from '../../../components/loading/loading.component';
import Tooltip from '../../../components/tooltip/tooltip.component';
import ReactList from 'react-list';
import './error.styles.scss';
class ErrorPage extends React.Component {
constructor() {
super();
this.state = {
pending: true,
errors: []
}
};
componentDidMount() {
axios.get('/api/logError').then(resp => {
this.setState({ pending: false, errors: resp.data });
}).catch(() => toastr('error', 'Eroare la preluarea datelor!'));
};
renderItem = (index, key) => {
return (
<tr key={key}>
<td>
{this.state.errors[index].id}
</td>
</tr>
)
};
renderTable (items, ref) {
return (
<div style={{maxHeight: '400px', overflowY: 'scroll'}}>
<Table bordered striped hover size="sm">
<tbody ref={ref}>
{items}
</tbody>
</Table>
</div>
);
}
renderRow = (index, key) => {
const entry = this.state.errors[index]
return (
<tr key={key}>
<td width='40px' className='text-center'>{index}</td>
<td width='40px' className='text-center'>{entry.id_user}</td>
<td width='200px'>{entry.email}</td>
<td width='200px'>{entry.name}</td>
<td width='200px'>{entry.action}</td>
<td>{entry.error}</td>
<td width='120px' className='text-center'><DaysJS format='DD.MM.YYYY - HH:MM'>{entry.createdAt}</DaysJS></td>
<td width='30px' className='cursor-pointer text-center' data-tip data-for='tooltip'>
<Tooltip id='tooltip' message='Șterge eroare'/>
<FontAwesomeIcon className='text-danger' icon={faTrashAlt} />
</td>
</tr>
);
}
render() {
const { pending, errors } = this.state;
return (
<div className='error-page mt-3 row'>
<Loading pending={pending} />
<div className='col-sm-4 fw-bold'>Total erori: {errors.length}</div>
<div className='col-sm-4'>
<h4 className='text-center'>Erori</h4>
</div>
<div className='col-sm-4 text-end'>
<button className='btn btn-danger btn-sm'>
<FontAwesomeIcon icon={faTrashAlt} className='me-1' />
Șterge toate
</button>
</div>
<div className='col-sm-12'>
<Table bordered size="sm">
<thead>
<tr>
<th width='40px'>Id user</th>
<th width='200px'>Email</th>
<th width='200px'>Unitate</th>
<th width='200px'>Acțiune</th>
<th>Eroare</th>
<th width='120px'>Data</th>
<th width='38px'></th>
</tr>
</thead>
</Table>
<ReactList
itemsRenderer={(items, ref) => this.renderTable(items, ref)}
itemRenderer={this.renderRow}
length={errors.length}
/>
</div>
</div>
);
};
};
export default ErrorPage;
I used in AngularJS a library called ng-infinite-scroll that rendered the items with no problem with infinite scroll and I tried to find something similar for ReactJS.
export class Diet extends Component {
render() {
return (
<SearchBar/>
<List>
<TouchableOpacity>
<Text>Foods</Text>
</TouchableOpacity>
</List>
)}}
Hey everyone, I can't figure out the following: I am trying to search foods from the database Edamam API by the SearchBar and list them in the List, this is the link of the page: https://developer.edamam.com/food-database-api-docs how can I do this?
Using Axios you can use your API url and using the state you can store the data and use it.
import React, {Component} from 'react';
import {Button, Card, CardBody, Col, Input, Modal, ModalBody, ModalFooter, ModalHeader, Row, Table} from "reactstrap";
import axios from 'axios';
import {FormGroup} from "react-bootstrap";
import InputColor from "react-input-color";
class labelx extends Component {
state = {
labels: []
}
componentWillMount() {
axios.get('http://APIURL').then(response => {
this.setState({
labels: response.data.data
})
}).then(console.log(this.state))
;
}
render() {
let projects = this.state.labels.map((book) => {
return (
<tr key={book.id}>
<td>{book.name}
</td>
<td style={{backgroundColor: book.color}}>{book.color}</td>
<td>
<Button color="danger" onClick={this.deleteProperty.bind(this, book.id)}>Delete</Button>
</td>
</tr>
)
});
return (
<>
<div className="content">
<Row>
<Col md="12">
<Card>
<CardBody>
<div className="content">
<div className="card-header">
<Table>
<thead>
<tr>
<th>name</th>
<th>color</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{projects}
</tbody>
</Table>
</div>
</div>
</CardBody>
</Card>
</Col>
</Row>
</div>
</>
);
}
}
export default labelx;
React router not rendering my JSX. The initial page renders the content inside. When I click add employee it doesn't display the content of the components. It renders a blank page. I'm a beginner in React.
CreateEmployeeComponent.jsx renders a blank page.
Below is the code of each file. Thanks in advance
App.js
import './App.css';
import React from 'react';
import ListEmployeeComponent from './components/ListEmployeeComponent';
import CreateEmployeeComponent from './components/CreateEmployeeComponent';
import HeaderComponent from './components/HeaderComponent';
import FooterComponent from './components/FooterComponent';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
function App() {
return (
<div>
<Router>
<div>
<HeaderComponent />
<div className="container">
<Switch>
<Route path="/" exact component={ListEmployeeComponent}></Route>
<Route path="/employees" component={ListEmployeeComponent}></Route>
<Route path="/add-emplyee" component={CreateEmployeeComponent}></Route>
</Switch>
</div>
<FooterComponent />
</div>
</Router>
</div>
);
}
export default App;
ListEmployeeComponent
import React, { Component } from 'react';
import EmployeeService from '../services/EmployeeService';
class ListEmployeeComponent extends Component {
constructor(props) {
super(props)
this.state = {
employees: []
}
this.addEmployee = this.addEmployee.bind(this);
}
componentDidMount() {
EmployeeService.getEmployees().then((res) => {
this.setState({ employees: res.data });
})
}
addEmployee() {
this.props.history.push('/add-employee');
}
render() {
return (
<div>
<h2 className="text-center">Employees List</h2>
<div className="row">
<button className="btn btn-primary" onClick={this.addEmployee}>Add Employee</button>
</div>
<div className="row">
<table className="table table-striped table-bordered">
<thead>
<tr>
<th>Employee First Name</th>
<th>Employee Last Name</th>
<th>Employee Email Id</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{
this.state.employees.map(
employee =>
<tr key={employee.id}>
<td> {employee.firstName} </td>
<td> {employee.lastName} </td>
<td> {employee.emailId} </td>
</tr>
)
}
</tbody>
</table>
</div>
</div>
);
}
}
export default ListEmployeeComponent;
CreateEmployeeComponent
import React, { Component } from 'react';
class CreateEmployeeComponent extends Component {
render() {
return (
<div>
<h1>Create Employee...</h1>
</div>
);
}
}
export default CreateEmployeeComponent;
You got type mistake : /add-emplyee -> /add-employee.
<Route path="/add-emplyee" component={CreateEmployeeComponent}></Route>
Please check it first