How to display data with id React Js and Firebase - javascript

I'm working on a project, and I would like to display some data from my firebase database,
I can show some of them, but I want to display the rest of the data of my "listClients" on a box, linked to the checkbox with the id.
listClients.js it's where i map the data from the db
import React, { Component } from "react";
import * as firebase from "firebase";
import { Table, InputGroup } from "react-bootstrap";
class ListClients extends React.Component {
state = {
loading: true
};
componentWillMount() {
const ref = firebase.database().ref("listClients");
ref.on("value", snapshot => {
this.setState({ listClients: snapshot.val(), loading: false });
});
}
render() {
if (this.state.loading) {
return <h1>Chargement...</h1>;
}
const clients = this.state.listClients.map((client, i) => (
<tr key={i}>
<td>
<input id={client.id} type="checkbox" onChange={this.cbChange} />
</td>
<td>{client.nom}</td>
<td>{client.prenom}</td>
</tr>
));
const clientsAdresses = this.state.listClients.map((clientAdresse, i) => (
<tr key={i}>
<td id={clientAdresse.id}>{clientAdresse.adresse}</td>
</tr>
));
return (
<>
<Table className="ContentDesign" striped bordered hover>
<thead>
<tr>
<th></th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>{clients}</tbody>
</Table>
<Table className="ContentDesign" striped bordered hover>
<thead>
<tr>
<th>Adresse : </th>
</tr>
</thead>
<tbody>{clientsAdresses}</tbody>
</Table>
</>
);
}
}
export default ListClients;
my data :
I only want the "adresse" of the id where the checkbox is check
Thank you
ERROR :

To retrieve the adresse from the database then use the following code:
componentWillMount() {
const ref = firebase.database().ref("listClients");
ref.on("value", snapshot => {
snapshot.forEach((subSnap) => {
let address = subSnap.val().adresse;
});
});
}
First add a reference to node listClients the using forEach you can iterate and retrieve the adresse
If you want to get the adresse according to the id, then you can use a query:
const ref = firebase.database().ref("listClients").orderByChild("id").equalTo(0);

Related

TypeScript: Property 'data' does not exist on type '{ children?: ReactNode; }'. ts(2339)

Question
I'm working on a small project with BlitzJS. I'm fetching some data but I keep getting this Typescript issue:
Property 'data' does not exist on type '{ children?: ReactNode; }'.ts(2339)
import { BlitzPage } from "blitz"
import Layout from "app/core/layouts/Layout"
export async function getServerSideProps() {
const response = await fetch(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=eur&order=market_cap_desc&per_page=10&page=1&sparkline=false"
)
const data = await response.json()
return {
props: {
data,
},
}
}
const MarketPage: BlitzPage = ({ data }) => { /////////// ERROR IS ON THIS LINE
console.log(data)
return (
<div>
<h1>This is Market Page</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Current Price</th>
</tr>
</thead>
<tbody>
{data.map((coin) => (
<tr key={coin.id}>
<td>
<p>{coin.name}</p>
</td>
<td>
<p>{coin.current_price}</p>
</td>
</tr>
))}
</tbody>
</table>
</div>
)
}
MarketPage.suppressFirstRenderFlicker = true
MarketPage.getLayout = (page) => <Layout>{page}</Layout>
export default MarketPage
I guess it's something with Typescript types but I don't work with Typescript so much. I'm having hard time finding solution.
Please can you help me with some guidance here.
Thanks!
Solution
Thanks to Ajay, I resolved the issue!
Here's working example:
import { BlitzPage } from "blitz"
import Layout from "app/core/layouts/Layout"
import { Table, Th, Td } from "app/core/components/Table"
interface CoinType {
id: string
name: string
current_price: string
}
interface PropType {
data: CoinType[]
}
export async function getServerSideProps() {
const response = await fetch(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=eur&order=market_cap_desc&per_page=10&page=1&sparkline=false"
)
const data = await response.json()
return {
props: {
data,
},
}
}
const MarketPage: BlitzPage<PropType> = ({ data }) => {
return (
<div>
<h1>This is Market Page</h1>
<Table>
<thead>
<tr>
<Th>Name</Th>
<Th hasNumber>Current Price</Th>
</tr>
</thead>
<tbody>
{data.map((coin) => (
<tr key={coin.id}>
<Td>
<p>{coin.name}</p>
</Td>
<Td hasNumber>
<p>{coin.current_price}</p>
</Td>
</tr>
))}
</tbody>
</Table>
</div>
)
}
MarketPage.suppressFirstRenderFlicker = true
MarketPage.getLayout = (page) => <Layout>{page}</Layout>
export default MarketPage
Typescript is showing errors because, You had not explain any type. You can create your type with
interface CoinType {
id: string;
name: string;
current_price: string;
}
interface PropType {
data: CoinType[];
}
Once You have created Types, then
const MarketPage: BlitzPage = ({ data }:PropType) => {
console.log(data)
return (
<div>
<h1>This is Market Page</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Current Price</th>
</tr>
</thead>
<tbody>
{data.map((coin) => (
<tr key={coin.id}>
<td>
<p>{coin.name}</p>
</td>
<td>
<p>{coin.current_price}</p>
</td>
</tr>
))}
</tbody>
</table>
</div>
)
}
I hope It would work correctly :-)

Fetching data and conditional rendering with React useEffect

I'm building a MERN stack app that fetches data about college classes and render it in a table. The CoursesTable.js component looks like this:
import React, { useState, useEffect } from 'react';
import { Table } from 'react-materialize';
import axios from 'axios';
const CoursesTable = () => {
const [courses, setCourses] = useState([]);
useEffect(() => {
const fetchData = async () => {
const coursesData = await axios.get('http://localhost:8001/')
setCourses(coursesData.data)
}
fetchData()
}, [])
return (
<Table>
<thead>
<tr>
<th data-field="course-name">
Name
</th>
<th data-field="course-prof">
Prof.
</th>
<th data-field="course-code">
Code
</th>
</tr>
</thead>
<tbody>
{
courses.length >= 1
? courses.map(course =>
<tr key={course._id}>
<td>
{course.name}
</td>
<td>
{course.prof}
</td>
<td>
{course.code}
</td>
</tr>
)
: <tr>
<td>There is no course</td>
</tr>
}
</tbody>
</Table>
);
}
export default CoursesTable;
I use conditional rendering so that if courses is empty, a message that goes like There is no course is displayed. When the array is full, the data is rendered in table rows.
My issue is: when courses is full and CoursesTable.js is rendered, the There is no course message always comes up for just a few milliseconds before being replaced with the data.
How can I fix this? Thanks for your help guys!
You could have a conditional check in place, e.g.:
import React, { useState, useEffect } from 'react';
import { Table } from 'react-materialize';
import axios from 'axios';
const CoursesTable = () => {
const [courses, setCourses] = useState([]);
const [isLoading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
const coursesData = await axios.get('http://localhost:8001/')
setCourses(coursesData.data)
setLoading(false);
}
fetchData()
}, [])
if(isLoading) { return <div> Loading ... </div> };
return (
<Table>
<thead>
<tr>
<th data-field="course-name">
Name
</th>
<th data-field="course-prof">
Prof.
</th>
<th data-field="course-code">
Code
</th>
</tr>
</thead>
<tbody>
{
courses.length >= 1
? courses.map(course =>
<tr key={course._id}>
<td>
{course.name}
</td>
<td>
{course.prof}
</td>
<td>
{course.code}
</td>
</tr>
)
: <tr>
<td>There is no course</td>
</tr>
}
</tbody>
</Table>
);
}
export default CoursesTable;

Sorting Html table Columns reactjs

i am trying to sort html table by ASC and desc order but this table is not working properly its working only for first column when i put id name can you please help me for make this work sorting func by ASC and Desc. this is my code so far i tried but its not working Thanks
import React from "react";
class Th extends React.Component {
handleClick = () => {
const { onClick, id } = this.props;
onClick(id);
};
render() {
const { value } = this.props;
return <th onClick={this.handleClick}>{value}</th>;
}
}
class App extends React.Component {
state = {
users: []
};
async componentDidMount() {
const res = await fetch(
`https://run.mocky.io/v3/6982a190-6166-402e-905f-139aef40e6ef`
);
const users = await res.json();
this.setState({
users
});
}
handleSort = id => {
this.setState(prev => {
return {
[id]: !prev[id],
users: prev.users.sort((a, b) =>
prev[id] ? a[id] < b[id] : a[id] > b[id]
)
};
});
};
render() {
const { users } = this.state;
return (
<table>
<thead>
<tr>
<Th onClick={this.handleSort} id="mileage" value="Mileage" />
<Th onClick={this.handleSort} id="overall_score" value="Overall score" />
<Th onClick={this.handleSort} id="fuel_consumed" value="Fuel Consumed" />
</tr>
</thead>
<tbody>
{users.map(user => (
<tr>
<td>{user.span.mileage.value}</td>
<td>{user.span.overall_score.value}</td>
<td>{user.span.fuel_consumed.value}</td>
</tr>
))}
</tbody>
</table>
);
}
}
export default App;
To make it works you need to change a few thigs:
the setState merges new data with old one, so [id]: !prev[id] adds new property to state for each column you filter without removing old one. It's better to store column to filter in dedicated state property (e.g. sortBy).
fix sorting function to make it sorting the users by correct object properties
remove async from componentDidMount and change fetch to use then/catch instead of async/await (it makes your code more React-ish).
Use example below as an inspiration:
class App extends React.Component {
state = {
sortBy: null,
order: "ASC",
users: []
};
componentDidMount() {
fetch(`https://run.mocky.io/v3/6982a190-6166-402e-905f-139aef40e6ef`)
.then(response => response.json())
.then(users => this.setState({users}))
.catch(err => console.log('Error', err));
}
handleSort = id => {
this.setState(prev => {
const ordered = prev.users.sort((a, b) =>
prev.order === "ASC"
? a["span"][id]["value"] < b["span"][id]["value"]
: a["span"][id]["value"] > b["span"][id]["value"]
);
return {
sortBy: id,
order: prev.order === "ASC" ? "DESC" : "ASC",
users: ordered
};
});
};
render() {
const { users } = this.state;
return (
<table>
<thead>
<tr>
<Th onClick={this.handleSort} id="mileage" value="Mileage" />
<Th
onClick={this.handleSort}
id="overall_score"
value="Overall score"
/>
<Th
onClick={this.handleSort}
id="fuel_consumed"
value="Fuel Consumed"
/>
</tr>
</thead>
<tbody>
{users.map(user => (
<tr>
<td>{user.span.mileage.value}</td>
<td>{user.span.overall_score.value}</td>
<td>{user.span.fuel_consumed.value}</td>
</tr>
))}
</tbody>
</table>
);
}
}
class Th extends React.Component {
handleClick = () => {
const { onClick, id } = this.props;
onClick(id);
};
render() {
const { value } = this.props;
return <th onClick={this.handleClick}>{value}</th>;
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Keep in mind that in only works with the current data schema and fields you already have. If you want to change the fields to sort by you need to update sorting function.

Not able to show fetched data from firebase into reactjs webapp

import React, { Component } from 'react'
import * as ReactBootStrap from 'react-bootstrap'
import { Table } from 'react-bootstrap'
import firebase from '../fire'
import '../App.css'
import Foot from './Foot'
class Appointment extends Component {
state = {
data: []
}
componentDidMount() {
firebase.database().ref("appoinment").once("value").then(snapShot => {
snapShot.forEach(item => {
this.state.data.push({
id: item.key,
name: item.val().name,
age: item.val().age,
gender: item.val().gender,
Description: item.val().Description,
date: item.val().Appointdate
});
})
})
}
render() {
return (
<div className='cardback'>
<div>
<br></br>
{console.log(this.state)}
<br></br>
<h2 style={{ textAlign: 'center', fontSize: '30px' }}>Today's Appointment</h2>
<br></br>
<br></br>
<Table striped bordered hover variant="dark" style={{ width: "1200px", margin: 'auto' }}>
<thead>
<tr>
<td>id</td>
<td>name</td>
<td>age</td>
<td>gender</td>
<td>Description</td>
<td>date</td>
<td>Status</td>
</tr>
</thead>
<tbody>
**{
this.state.data.map((item) =>
<tr>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.age}</td>
<td>{item.gender}</td>
<td>{item.Description}</td>
<td></td>
</tr>
)
}**
</tbody>
</Table>
<br></br>
<br></br>
</div>
<Foot></Foot>
</div>
)
}
}
export default Appointment;
This is above is code
I want to fetch data from the firebase to react-js application. I am able to get whole data at the console but not able to iterate it into table form. The is as below. In which I fetch data from firebase and pushed into an array data. So basically data is an array of objects. But I am not able to iterate i
You are mutating the state directly which will not cause any re-render. Don't do this.state.data.push({id:item.key,
Use this.setState
componentDidMount() {
firebase
.database()
.ref("appoinment")
.once("value")
.then((snapShot) => {
let updatedData = [];
snapShot.forEach((item) => {
updatedData.push({
id: item.key,
name: item.val().name,
age: item.val().age,
gender: item.val().gender,
Description: item.val().Description,
date: item.val().Appointdate,
});
});
this.setState({ data: updatedData });
});
}

How can I sort column in child component clicking on heading in parent component?

The problem is I don't know how to put effect from parent component to child component...
I'm creating sorting function.
tableSort = (event, sortKey) => {
const {data} = this.state;
data.sort((a,b) => a[sortKey].localeCompare(b[sortKey]) )
this.setState({ data })
}
and then I'm trying to render that in my table
render() {
const {data} = this.state
return (
<>
<Table>
<Thead>
<Tr>
<Th onClick={e => this.tableSort(e, 'pool number')}>Pool Number</Th>
<Th>Sender</Th>
<Th>Not Routed Reason</Th>
<Th>Sent Date Time</Th>
<Th>Requested Delivery Report Mask Text</Th>
<Th>Delivery Report Received Date Time</Th>
<Th>isUnicode</Th>
<Th>MessageUUID</Th>
</Tr>
</Thead>
{this.renderData(data)}
</Table>
</>
)
}
The child component is called in this component and it locks like this..
import React from 'react'
import { Tbody, Tr, Td } from 'react-super-responsive-table'
const TablePageList = ({data}) => {
const {poolNumber, sender, notRoutedReason, sentDateTime, requestedDeliveryReportMaskText,
deliveryReportReceivedDateTime, isUnicode, messageUUID} = data
return (
<Tbody>
<Tr>
<Td>{poolNumber}</Td>
<Td>{sender}</Td>
<Td>{notRoutedReason}</Td>
<Td>{sentDateTime}</Td>
<Td>{requestedDeliveryReportMaskText}</Td>
<Td>{deliveryReportReceivedDateTime}</Td>
<Td>{isUnicode}</Td>
<Td>{messageUUID}</Td>
</Tr>
</Tbody>
)
}
export default TablePageList
So how can I access and sort my Td from Th?
You should call the child component from parent. You didn't call any child component.
Try below code.
import child compenent url.
import TablePageList from "./TablePageList";
And then keep state data.
this.state = {
data:[]
}
Also change function setState and order data.
tableSort = (event, sortKey) => {
const {data} = this.state;
data.sort((a,b) => a[sortKey].localeCompare(b[sortKey]) )
this.setState({ data: data })
}
And call TablePageList component below </Thead>
render() {
const { data } = this.state;
return (
<Table>
<Thead>
<Tr>
<Th onClick={e => this.tableSort(e, "pool number")}>
Pool Number
</Th>
<Th>Sender</Th>
<Th>Not Routed Reason</Th>
<Th>Sent Date Time</Th>
<Th>Requested Delivery Report Mask Text</Th>
<Th>Delivery Report Received Date Time</Th>
<Th>isUnicode</Th>
<Th>MessageUUID</Th>
</Tr>
</Thead>
{data.map(element => {
<TablePageList data={element}></TablePageList>;
})}
</Table>
);
}
And then you get data and fill it.
const TablePageList = ({ data }) => {
return (
<Tbody>
<Tr>
<Td>{data.poolNumber}</Td>
<Td>{data.sender}</Td>
<Td>{data.notRoutedReason}</Td>
<Td>{data.sentDateTime}</Td>
<Td>{data.requestedDeliveryReportMaskText}</Td>
<Td>{data.deliveryReportReceivedDateTime}</Td>
<Td>{data.isUnicode}</Td>
<Td>{data.messageUUID}</Td>
</Tr>
</Tbody>
);
};

Categories

Resources