Am new to React, and it feels like its very difficult to carry out mathematical calculations with react, Have been trying to add up two values gotten from firebase database but it keeps displaying the values as string and not adding the two values, Please I need help.
{contactObjects[id].gcc} + {contactObjects[id].lcc}
adding this two will only display all as string
E.g
if {contactObjects[id].gcc} is = 10 in firebase datebase and {contactObjects[id].lcc} as = 30
And adding + to the code wont sum up the two values, it will only display them as
10 + 30 which is in string and not 40
Please how can i go about it.
import React, { useState, useEffect } from "react";
import ContactForm from "./ContactForm";
import firebaseDb from "../firebase";
const Contacts = () => {
var [contactObjects, setContactObjects] = useState({});
var [currentId, setCurrentId] = useState("");
useEffect(() => {
firebaseDb.child("contacts").on("value", (snapshot) => {
if (snapshot.val() != null)
setContactObjects({
...snapshot.val(),
});
else setContactObjects({});
});
}, []); // similar to componentDidMount
const addOrEdit = (obj) => {
if (currentId == "")
firebaseDb.child("contacts").push(obj, (err) => {
if (err) console.log(err);
else setCurrentId("");
});
else
firebaseDb.child(`contacts/${currentId}`).set(obj, (err) => {
if (err) console.log(err);
else setCurrentId("");
});
};
const onDelete = (key) => {
if (window.confirm("Are you sure to delete this record?")) {
debugger;
firebaseDb.child(`contacts/${key}`).remove((err) => {
if (err) console.log(err);
else setCurrentId("");
});
}
};
return (
<>
<div className="jumbotron jumbotron-fluid">
<div className="container">
<h1 className="display-4 text-center">Contact Register</h1>
</div>
</div>
<div className="row">
<div className="col-md-5">
<ContactForm {...{ addOrEdit, currentId, contactObjects }} />
</div>
<div className="col-md-7">
<table className="table table-borderless table-stripped">
<thead className="thead-light">
<tr>
<th>Full Name</th>
<th>Mobile</th>
<th>Email</th>
<th>Address</th>
<th>Street</th>
<th>Address</th>
<th>Gcc</th>
<th>Lcc</th>
</tr>
</thead>
<tbody>
{Object.keys(contactObjects).map((id) => {
return (
<tr key={id}>
<td>{contactObjects[id].fullName}</td>
<td>{contactObjects[id].mobile}</td>
<td>{contactObjects[id].email}</td>
<td>{contactObjects[id].address}</td>
<td>{contactObjects[id].street}</td>
<td>{contactObjects[id].gcc}</td>
<td>{contactObjects[id].lcc}</td>
<td>
{contactObjects[id].gcc} +
{contactObjects[id].lcc}
</td>
<td>
<a
className="btn text-primary"
onClick={() => {
setCurrentId(id);
}}
>
<i className="fas fa-pencil-alt"></i>
</a>
<a
className="btn text-danger"
onClick={() => {
onDelete(id);
}}
>
<i className="far fa-trash-alt"></i>
</a>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</>
);
};
export default Contacts;
If I understand correctly, then just parse these values to int. If in DB these are 'string'
{parseInt(contactObjects[id].gcc) + parseInt(contactObjects[id].lcc)}
Related
I am trying to filter results based on a selection from a drop down.
Scenario:
I have data coming in from MSSQL into NextJS with the help of Prisma (ORM) and I want to have a filter, preferably a drop-down that will filter the results based on the selection on the drop-down.
Here's what I have done so far;
/checkin/index.js
import Head from "next/head";
import { PrismaClient } from "#prisma/client";
import { NavBar } from "../../components/Layouts/NavBar";
import provs from "../../assets/prov.json";
import { useState } from "react";
const prisma = new PrismaClient();
export async function getServerSideProps() {
const interviews = await prisma.sdesmain.findMany();
return {
props: { interviews },
};
}
export default function Checkin({ interviews }) {
const [provinceFilter, setProvinceFilter] = useState();
const [filterInterviews, setFilterInterviews] = useState(interviews);
const handleProvinceFilter = (e) => {
const provCode = e.target.value;
setProvinceFilter(provCode);
if (provCode === "all") {
setFilterInterviews(interviews);
}
};
const filteredInterviews = filterInterviews.filter((interview) => {
if (interview.a01_province === provinceFilter) {
return interview;
}
});
return (
<div>
<NavBar />
<div className="container mx-auto">
<div>
<h1 className="text-3xl font-bold">Interviews checkin</h1>
</div>
<div className="flex flex-col py-6">
<select
className="bg-gray-200 rounded-md p-2 max-w-md"
onChange={handleProvinceFilter}
>
<option value="all">All</option>
{provs.map((prov) => (
<option value={prov.id} key={prov.id}>
{prov.provinceName}
</option>
))}
</select>
</div>
</div>
<div className="container mx-auto">
<h1>Interviews by Household / Cluster </h1>
<div className="overflow-x-auto relative ">
<table className="table-auto w-full text-sm text-left text-gray-800 dark:text-gray-800 ">
<thead>
<tr>
<th>Province Code</th>
<th>Cluster Number</th>
<th>Household Sample Number</th>
</tr>
</thead>
<tbody>
{filterInterviews.map((interview) => (
<tr key={interview.interview_key}>
<td>{interview.a01_province}</td>
<td>{interview.a02_clusterNumber}</td>
<td>{interview.a06_hhsampleNumber}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
);
}
// Language: javascript
// Path: pages/checkin/index.js
Although data is being displayed, it's not filtered by the drop down.
How do I go about making this to work?
you need to filter interviews using filterInterviews state variable
const filteredInterviews = interviews.filter(interview => {
if (provinceFilter === 'all') return true;
return interview.interview.a01_province === filterInterviews)
}
then render filteredInterviews instead of interviews
I figured it out.
I was trying to match the select value (of string type) to a number.
I ran the event value e.target.value for the drop down through parseInt(e.target.value), then match the value with province code from db with the filter function.
const handleProvinceFilter = (e) => {
setProvinceFilter(parseInt(e.target.value));
};
const filteredInterviews = interviews.filter(
(interview) => interview.a01_province === provinceFilter
);
I want to make my table row dynamic so it can automatically add new data from the MySQL database but I don't know how. Can you help me?
Here is my static data that I wanted to make dynamic.
const data = {
rows: [
{
Campus_name: 'National Arabella SHS',
tel_number: ' 123-12-123',
action:
<div className='action-icon-container'>
<Tooltip title="Edit" trigger="hover">
<Link to='/admin/campus/edit-campus/:id' state={{bc_edit_type : 1}}><MdEdit className='action-icon edit' /></Link>
</Tooltip>
</div>
},
{
Campus_name: 'College of Arabella - Main',
tel_number: ' 123-12-123',
action:
<div className='action-icon-container'>
<Tooltip title="Edit" trigger="hover">
<MdEdit className='action-icon edit' />
</Tooltip>
</div>
},
{
Campus_name: 'College of Arabella Extension',
tel_number: ' 123-12-123',
action:
<div className='action-icon-container'>
<Tooltip title="Edit" trigger="hover">
<MdEdit className='action-icon edit' />
</Tooltip>
</div>
},
]
};
Here is the part where I get the data from the database and store it in 'campusValues' variable.
const CampusPage = () => {
const [campusValues, setCampusValues] = useState([]);
const GetCampusValues = () => {
Axios.get("http://localhost:5000/campusValues").then((response) => {
console.log(response);
setCampusValues(response.data);
});
}
useEffect(() => {
let ignore = false;
if (!ignore)
GetCampusValues();
return () => { ignore = true; }
},[]);
return (...);
}
export default CampusPage
To make a dynamic table just map the table rows:
<table>
<tr>
<th>...</th>
<th>...</th>
<th>...</th>
</tr>
{
campusValues.map(value => (
<tr key={...}>
<td>{value.id}</td>
<td>{value.name}</td>
<td>...</td>
</tr>
))
}
</table>
I've added a search bar to my React-Firebase Dashboard.As a result, the search bar is displayed with the table of clients stored in Cloud Firestore, when I enter a text in the search bar It returns an empty table even if that word exists in the table.
PS: Both of the Results are shown below in screenshots
The table initially rendered
table after writing anything in the search bar
Customer.js
import React, { Fragment, useState } from "react";
import { Avatar } from '#material-ui/core';
import PageTitle from "../../../../layouts/PageTitle";
import { Dropdown, Table } from "react-bootstrap";
import { fire } from "../../../../../fire";
import { firestore } from "../../../../../fire";
import { collection, query, where } from "../../../../../fire";
import App from "../../../../../App";
export default class Recipe extends React.Component {
state = {
searchTerm : "",
Users: []
}
constructor(props){
super(props);
}
searchByTerm = (value) => {
this.setState({searchTerm : value});
}
componentDidMount() {
firestore.collection("Users").get().then((querySnapshot) => {
let User = []
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data().lastn}`);
User.push({
id : doc.id,
data: doc.data()})
});
this.setState({Users : User})
});
}
delete = (id) => {
console.log(id)
firestore.collection("Users").doc(id).delete().then(() => {
console.log("Document successfully deleted!");
this.props.history.push("#")
}).catch((error) => {console.error("Error removing document: ",
error);
});
}
render() {
return (
<Fragment>
<div className="col-12">
<div className="card">
<div className="card-header">
<div className="input-group search-area d-lg-inline-flex d-none mr-
5">
<input
type="text"
className="form-control"
placeholder="Search here"
onChange ={(e) => {
this.searchByTerm(e.target.value);
}}
/>
<div className="input-group-append">
<span className="input-group-text"
>
<svg
width={20}
height={20}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M23.7871 22.7761L17.9548 16.9437C19.5193 15.145 20.4665 12.7982 20.4665 10.2333C20.4665 4.58714 15.8741 0 10.2333 0C4.58714 0 0 4.59246 0 10.2333C0 15.8741 4.59246 20.4665 10.2333 20.4665C12.7982 20.4665 15.145 19.5193 16.9437 17.9548L22.7761 23.7871C22.9144 23.9255 23.1007 24 23.2816 24C23.4625 24 23.6488 23.9308 23.7871 23.7871C24.0639 23.5104 24.0639 23.0528 23.7871 22.7761ZM1.43149 10.2333C1.43149 5.38004 5.38004 1.43681 10.2279 1.43681C15.0812 1.43681 19.0244 5.38537 19.0244 10.2333C19.0244 15.0812 15.0812 19.035 10.2279 19.035C5.38004 19.035 1.43149 15.0865 1.43149 10.2333Z"
fill="#A4A4A4"
/>
</svg>
</span>
</div> </div>
<h4 className="card-title">Customer List </h4>
</div>
<div className="card-body">
<Table responsive className="w-100">
<div id="example_wrapper" className="dataTables_wrapper">
<table id="example" className="display w-100 dataTable">
<thead>
<tr role="row">
<th>Avatar</th>
<th>Email</th>
<th>Firstname</th>
<th>Lastname</th>
<th>PhoneNumber</th>
{/* <th className="pl-5 width200">
Billing Address
</th> */}
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.Users.filter( (val) =>{
const { email = "", firstname = "" } = val;
// console.log(this.state.searchTerm);
if (this.state.searchTerm === "") {
return val;
} else if (
email.toLowerCase().includes(this.state.searchTerm.toLowerCase()) ||
firstname.toLowerCase().includes(this.state.searchTerm.toLowerCase())
) {
return val;
}
}).map(data => {
return (
<tr>
<td> <Avatar className ="rounded-circle img-fluid" src={data.data.avatar}/> </td>
<td>{data.data.email}</td>
<td>{data.data.firstname}</td>
<td>{data.data.datalastname}</td>
<td>{data.data.phonenumber}</td>
<td>
<div
className="btn btn-danger shadow btn-xs sharp" onClick ={this.delete.bind(this, data.id)}
>
<i className="fa fa-trash"></i> </div></td>
</tr>
);
})}
</tbody>
</table>
</div>
</Table>
</div>
</div>
</div>
</Fragment>
);
};
};
Array.prototype.filter callback should be returning a boolean, not the element being iterated over.
This is how I suggest rewriting your filter function: if there is no search term (i.e. falsey) then return true to indicate all elements iterated over should be return, otherwise, return the result of the comparison.
const { Users, searchTerm } = this.state;
const term = this.state.searchTerm.toLowerCase();
...
Users.filter((val) => {
const { data: { email = "", firstname = "" } = {} } = val;
if (term) {
return (
email.toLowerCase().includes(term) ||
firstname.toLowerCase().includes(term)
);
}
return true;
})
A slightly more succinct version could be written as follows:
const { Users, searchTerm } = this.state;
const term = this.state.searchTerm.toLowerCase();
...
Users.filter(({ data: { email = "", firstname = "" } = {} }) =>
term ? email.concat(firstname).toLowerCase().includes(term) : true
)
Update
After you've stated that you implemented my suggestions and it's still not working I took a closer look at what you are rendering and noticed that in the .map callback you reference each field (email, firstname, etc...) from a data property on each element. Since it seems you are able to render your data when no filter is being applied I'll assume this structure to be correct. As such then, the .filter callback needs to also reference the nested field properties from a data property. I've updated the above code snippets.
Here I have got the two .json files named users.json and subscription.json. In JSON file users.id links to subscription.user_id. I have view the data of subscription.json in the table.
Now I want to get the username using id of users.json linked to user_id of subscription.json
import React, {useEffect, useState} from 'react'
import '../UserList/userlist.css'
const Suscriber = () => {
const [search, setSearch] = useState([]);
const [data,setData]=useState([]);
const [order, setorder] = useState("ASC");
const [users,setUsers] = useState([{}])
useEffect(()=>{
fetch('data/users.json').then((res)=>res.json()).then((data)=>{
setUsers(data)
})
},[])
const getData=()=>{
fetch('./data/subscriptions.json'
,{
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
)
.then(function(response){
console.log(response)
return response.json();
})
.then(function(myJson) {
console.log(myJson);
setData(myJson)
});
}
useEffect(()=>{
getData()
},[])
const sorting = (col) => {
if (order === "ASC") {
const sorted = [...data].sort((a,b)=>
a[col].toString().toLocaleLowerCase() > b[col].toString().toLocaleLowerCase() ? 1 : -1
// ||
// a[col].Number.toLocaleLowerCase() < b[col].Number.toLocaleLowerCase() ? 1 : -1
);
setData(sorted);
setorder("DSC");
}
if (order === "DSC") {
const sorted = [...data].sort((a,b)=>
a[col].toString().toLocaleLowerCase() < b[col].toString().toLocaleLowerCase() ? 1 : -1
);
setData(sorted);
setorder("ASC");
}
}
return (
<div className="main">
<div className="search_option">
<h1 className="table-head">Subscribed User Data List</h1>
<div className="input-icons">
<i class="fa fa-search icon" aria-hidden="true"></i>
<input type="search"
className="input-field"
placeholder="Search......."
onChange={(event) => {
setSearch(event.target.value);
}}
/>
</div>
</div>
<table>
<thead>
<tr>
<th scope="col" onClick={()=>sorting("id")}>ID <i class="fas fa-sort sortings"></i></th>
<th scope="col" onClick={()=>sorting("user_id")}>User ID <i class="fas fa-sort sortings"></i></th>
<th scope="col">Username <i class="fas fa-sort sortings"></i></th>
<th scope="col" onClick={()=>sorting("package")}>Package <i class="fas fa-sort sortings"></i></th>
<th scope="col" onClick={()=>sorting("expires_on")}>Expire on <i class="fas fa-sort sortings"></i></th>
</tr>
</thead>
<tbody>
{data.filter((val) => {
if (search === ""){
return val
}
else if (
val.id.toString().toLocaleLowerCase().includes(search.toString().toLocaleLowerCase())
// || val.email.toLocaleLowerCase().includes(search.toLocaleLowerCase())
// || val.user_id.toString().toLocaleLowerCase().includes(search.toLocaleLowerCase())
|| val.package.toLocaleLowerCase().includes(search.toString().toLocaleLowerCase())
// || val.expires_on.toString().toLocaleLowerCase().includes(search.toLocaleLowerCase())
){
return val
}
return false;
}).map((val, key) => {
const user = users.find(uid => uid.id === val.user_id);
return <tr key={key}>
<td data-label="ID">{val.id}</td>
<td data-label="User ID">{val.user_id}</td>
<td data-label="Username">{user.username}
{/* {
subscribe.map((detail, index) => {
return <div>{detail.username}</div>
})
} */}
{/* {
subscribe.filter(uid => uid.id === val.user_id).map(details =>(
<>{details.username}</>
))
} */}
</td>
<td data-label="Package">{val.package}</td>
<td data-label="Expire on">{val.expires_on}</td>
</tr>
})}
</tbody>
</table>
</div>
)
}
export default Suscriber
The table includes all the data in subscriptions.json now need to find and display the same user_id and username from users.json and view it on the table below.
Below are users.json data picture:
Below are subscriptions.json data picture:
Instead of using Filter you can use the find method .
.map((val, key) => {
// Find the user
const user = subscribe.find(uid => uid.id === Number(val.user_id));
return <tr key={key}>
<td data-label="ID">{val.id}</td>
<td data-label="User ID">{val.user_id}</td>
<td data-label="Username">{ user?.username || '-' }</td>
<td data-label="Package">{val.package}</td>
<td data-label="Expire on">{val.expires_on}</td>
</tr>
})}
I have a problem. I'm lost in the deep forest of reactJs. I'm new here.
I have 8 components which I need to get via clicking on short-name button .
What are the steps.
I select what I need from the first filter and I get short_names and all the components without data.
I don't want to get all the components, i need just 1 component that I'll get by clicking on a short name.
Screenshot here
Here is code of rendering page:
import React, { Component } from 'react';
import { Link } from 'react-router';
import { getAll, getAllRates } from '../actions';
import { MODULE_NAME } from './index';
import { PanelHeader, PanelFooter, LocalFilter } from 'Components';
import locales from 'Shared/locales';
import search from 'Shared/search';
import sortBy from 'Shared/sortBy';
import { AvsProviders, FakProviders, LaaProviders, Laac1Providers,
Laac2Providers, Laac3Providers, MpgProviders, Mpg2Providers } from '../ComponentsProviders';
export default class ListsAccounting extends Component {
state = {
data: [],
le_id: null,
year: new Date().getFullYear(),
totalPages: 0,
searchString: '',
limit: '50',
page: 1,
};
search = search(this);
sortBy = sortBy(this);
loadData = (params) => {
const { searchString } = this.state;
const q = searchString === '' ? null : searchString;
getAll({ leId: this.state.le_id, name: MODULE_NAME, params: { q, year: this.state.year, ...params } })
.then(success => this.setState({
data: success.data,
totalPages: success.totalPages,
page: success.page,
limit: String(success.limit || ''),
}));
};
constructor() {
super();
this.onClick = this.handleClick.bind(this);
}
handleClick(event) {
const { id } = event.target;
console.log(id);
}
getData = (leId, id, type, year) => {
getAllRates({ leId, id, type, year, name: MODULE_NAME })
.then(() => this.loadData());
};
changeState = state => this.setState(state, () => this.loadData());
render() {
const { limit, totalPages, data } = this.state;
console.log(this);
return (
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-6">
<div className="panel panel-adminme table-dynamic">
<PanelHeader
name="insurances"
currentState={{
state: this.state,
loadData: this.loadData,
}}
/>
<div className="table-filters">
<div className="row no-x-margin">
<div className="col-sm-4 col-xs-6">
<LocalFilter
name="all-providers-leg-entities"
placeholder="le_id"
option="le_id"
value={this.state.le_id}
changeState={this.changeState}
/>
</div>
<div className="col-md-3 col-sm-4 col-xs-6">
<LocalFilter
name="insurance-years"
placeholder="year"
option="year"
value={this.state.year}
changeState={this.changeState}
/>
</div>
</div>
</div>
<div className="table-responsive">
<table className="table table-bordered table-striped table-hover">
<thead>
<tr className="text-center">
<th>
NAME
</th>
<th>
SHORT_NAME
</th>
<th>
ACTION
</th>
</tr>
</thead>
<tbody>
{
!data.length &&
<tr>
<td colSpan="3" className="text-center">
{locales('no_rows')}
</td>
</tr>
}
{
data.map((row, index) => (
<tr key={`${MODULE_NAME}-${index}`}>
<td>
<h5>{row.type}</h5>
</td>
<td>
{
row.text.map((name, indexText) => (
<span key={name} className="margin-right-10">
<Link
key={row.type}
role="button"
onClick={ () => this.getData(
this.state.le_id,
row.text_id[indexText],
row.type,
row.year,
)}
>
{name}
</Link>
</span >
))
}
</td>
<td className="btn btn-info">
ADD
</td>
</tr>
))
}
</tbody>
</table>
</div>
<PanelFooter
limit={limit}
totalPages={totalPages}
loadData={this.loadData}
/>
</div>
</div>
<div className="col-xs-12 col-sm-12 col-md-6">
{ data.type === data.type && data.text_id === data.text_id &&
data.map((row) => {
console.log(row.type);
switch (row.type) {
case 'AVS':
return (
<AvsProviders/>
);
case 'FAK' :
return (
<FakProviders/>
);
case 'LAA':
return (
<LaaProviders/>
);
case 'LAAC1':
return (
<Laac1Providers/>
);
case 'LAAC2':
return (
<Laac2Providers/>
);
case 'LAAC3':
return (
<Laac3Providers/>
);
case 'MPG':
return (
<MpgProviders/>
);
case 'MPG2':
return (
<Mpg2Providers/>
);
default:
return null;
}
})
}
</div>
</div>
</div>
);
}
}
Here is page of 1 of the rendering components:
import React, { Component } from 'react';
import { getAllRates } from '../../actions';
import { PanelHeader } from 'Components';
const MODULE_NAME = 'FAK';
export default class FakProviders extends Component {
state = {
data: [],
le_id: null,
year: new Date().getFullYear(),
totalPages: 0,
searchString: '',
limit: '50',
page: 1,
};
componentDidMount() {
this.loadData();
}
loadData = (params) => {
const { searchString } = this.state;
const q = searchString === '' ? null : searchString;
getAllRates({ leId: this.props.params.le_id,
id: this.props.params.text_id,
name: MODULE_NAME,
params: { q, ...params } })
.then(success => this.setState({
data: success.data,
totalPages: success.totalPages,
page: success.page,
limit: String(success.limit || ''),
}));
};
changeState = state => this.setState(state, () => this.loadData());
render() {
const { data } = this.state;
return (
<div className="panel panel-adminme table-dynamic">
<PanelHeader
name="insurances"
currentState={{
search: this.search,
state: this.state,
loadData: this.loadData,
}}
/>
<div className="table-responsive">
<table className="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>
<h4>{data.fak_short_name}</h4>
</th>
<th>
<h4>{data.year}</h4>
</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<h4>fak_rate_ee</h4>
</th>
<th>
<h4>
{data.fak_rate_ee}
</h4>
</th>
</tr>
<tr>
<th>
<h4>fak_rate_er</h4>
</th>
<th>
<h4>
{data.fak_rate_er}
</h4>
</th>
</tr>
</tbody>
</table>
</div>
<div className="panel-footer" />
</div>
);
}
}