Get data from Server DB table on React with condition - reactjs

Need help please... I have a fetchData function, getting the data from the DB Table Matricula, I just need to capture the records that have the date = Today
How can I only receive data where the date is the same as the current day?
class Matricula extends Component {
state = {
datos:[],
today: new Date()
}
componentDidMount = () => {
this.fetchData()
}
fetchData = async () => {
try {
const response = await getAll('matricula')
console.log("ver: ", response.data);
if (response.data.fecha.toLocaleString() === this.state.today.toLocaleDateString()) { // no se que me falta
this.setState({
status: "done",
datos: response.data,
});
}
} catch (error) {
this.setState({
status: "error"
});
}
};
render() {
const data = this.state.matriculas;
return (
<ReactTable
data={data}
contentEditable
filterable
collapseOnDataChange={false}
columns={[
{
Header: "Id",
accessor: "id"
},
{
Header: "Name",
accessor: "Name"
},
{
Header: "Date",
accessor: "date",
id: "date",
}
]
}
defaultPageSize={14}
className="-striped -highlight"
/>
)}
export default Matricula;
the getAll funcion is
export function getAll(entity){
return axios({
method: 'get',
baseURL: API_URL,
headers: headers(),
url: entity,
})
}

The optimal way would be to ask for the data that you need, that means asking only for the matriculas of today.
If you can't change this, what you should do is filter them before storing them in the state, something like this:
this.setState({
status: "done",
datos: response.data.filter((matricula)=>{
return matricula.date === this.state.today //not a proper dates comparison
}),
});
Here I'm assuming that your matriculas have an attribute date and I'm comparing it to your this.state.today to filter them out. Keep in mind that you should do a proper date comparison, and that depends on the format you are storing your data, this should help

Related

React-Query: how can I update cache pagination

I'm using Paginated for showing data and the user can remove the item. user after a click on the button remove send request delete and get response success.
I want to remove the item in catch react-query.
I don't want to use method refetch
get all items on the server :
const useGetAll = () =>
useQuery(['applications/getAll', page], () => axios.get<GetAllApplication>('localhost:...', { params: { page } }), {
keepPreviousData: true,
})
interface response data
interface GetAllApplication {
hasError: boolean
data: {
meta: {
itemsPerPage: number
totalItems: number
currentPage: number
totalPages: number
sortBy: [['id', 'DESC']]
}
response: {
id: number
name: string
status: 'enable' | 'disable'
}[]
}
}
remove item request with useMutation :
const useRemoveApplication = () =>
useMutation('applications/remove', removeApplication, {
onSuccess({ message },id ) {
toast(message, { type: 'success' })
},
})
You should use queryClient's method setQueryData in your onSuccess.
Reference: react-query docs

Populate React Table with firebase realtime database data

I want to populate my table which i build using react library (react-table-6) with firebase data (using realtime database). I am getting values in console but not being able to put in table, each value in its own field. Values are rendering but i know im doing some silly mistake here.
See this image to see screen
Can anybody explain what im doing wrong here,
Below dropping function through which im retrieving values..
State:
this.state = {
data: [ {trainerName: '', CourseName: '', evidence: '', comment: ''}
]}
function:
get_course_list(){
return firebase.database().ref('Users/CourseApprovals/').on('value', (snapshot) => {
var data = [];
snapshot.forEach((childSnapshot) => {
var childData= childSnapshot.val();
var child1 = childData.comments;
var child2 = childData.evidence;
var child3 = childData.selectedTrainer.label;
var child4 = childData.selectedTrainer.value;
var CompleteData = {child1, child2, child3, child4};
data.push({
data: CompleteData
});
})
this.setState({
data
}, console.log(data))
})
}
componentDidMount(){
this.get_course_list();
}
And in render,
<ReactTable
data={data}
columns={[
{ Header: "SL No", maxWidth: 100,filterable: false, Cell: props => {
return <div>{props.index + 1}</div>;
}},
{ Header: "Trainer Name", accessor: "trainerName", className: "sticky", headerClassName: "sticky" },
{ Header: 'Course Name', accessor: 'CourseName'},
{ Header: "Evidence", accessor: "evidence" },
{ Header: 'Comments', accessor: 'comment'},
]}
defaultPageSize={10}
className="-striped -highlight"
/>
The problem may be in pushing data twice into the data array. Try this:
get_course_list() {
let data = [];
firebase.database().ref('Users/CourseApprovals').on('value', snapshot => {
if (snapshot.exists()) {
// making sure data exists
snapshot.forEach(child => {
let a = child.val();
// build the object
let CompleteData = {
child1: a.comments,
child2: a.evidence,
child3: a.selectedTrainer.label,
child4: a.selectedTrainer.value
}
// you are currently doing: data.push({ data: CompleteData })
// by doing so your data array looks like this:
// data:[{ data: { child1: '', ... } }, ...]
data.push(CompleteData)
// now your array should look like this:
// data:[{ child1: '', ... }, ...]
});
// setState
this.setState({ data });
console.log(data);
}
})
}
componentDidMount() {
this.get_course_list();
}

Handling Graphql Mutation update, cache read and writeQuery, if the query is dynamic?

Doing nightlife app on freecodecamp https://learn.freecodecamp.org/coding-interview-prep/take-home-projects/build-a-nightlife-coordination-app/
I am trying to implement 'Go' button, similarly 'Like' button on Youtube or Instagram. Users click the button the number(counting how many users go) goes up meaning users will go there and click again, it revokes, the number decreases, users will not go there.
It seems like working well except the issue, I have to refresh the page and then, the number has increased or decreased and throws the error like below so:
Invariant Violation: Can't find field getBars({}) on object {
"getBars({\"location\":\"vancouver\"})": [
{
"type": "id",
"generated": false,
"id": "Bar:uNgTjA9ADe_6LWby20Af8g",
"typename": "Bar"
},
{
"type": "id",
"generated": false,
"id": "Bar:CwL5jwXhImT_7K5IB7mOvA",
"typename": "Bar"
},
{
"type": "id",
"generated": false,
"id": "Bar:mdt1tLbkZcOS2CsEbVF9Xg",
"typename": "Bar"
},
.
.
.
I am assuming handling update function will fix this issue but unlike the example from Apollo documentation:
// GET_TODOS is not dynamic query
// nothing to pass as variables to fetch TODO list
<Mutation
mutation={ADD_TODO}
update={(cache, { data: { addTodo } }) => {
const { todos } = cache.readQuery({ query: GET_TODOS });
cache.writeQuery({
query: GET_TODOS,
data: { todos: todos.concat([addTodo]) },
});
}}
>
My query is dynamic:
// I have to pass location variable, otherwise it won't fetch anything.
const GET_BARS_QUERY = gql`
query getBars($location: String!) {
getBars(location: $location) {
id
name
url
rating
price
image_url
goings {
username
}
goingCount
}
}
`;
I believe I might need to handle to provide location using readQuery and writeQury but not too sure what I should do.
Here's my code:
const GoButton = ({ user, bar }) => {
const { token } = user;
const { id, goings, goingCount } = bar;
const [userGoes] = useMutation(GO_MUTATION, {
variables: { yelp_id: id },
update(proxy, result) {
const data = proxy.readQuery({
query: GET_BARS_QUERY
});
data.getBars = [result.userGoes, ...data.getBars];
proxy.writeQuery({ query: GET_BARS_QUERY, data });
}
});
return (
<Button onClick={userGoes}>
Go {goingCount}
</Button>
);
};
const GO_MUTATION = gql`
mutation go($yelp_id: String!) {
go(yelp_id: $yelp_id) {
id
goings {
id
username
}
goingCount
}
}
`;
export default GoButton;
Full code here https://github.com/footlessbird/Nightlife-Coordination-App
when you read/write the getBars query, you need to pass the location as a variable
const [userGoes] = useMutation(GO_MUTATION, {
variables: { yelp_id: id },
update(proxy, result) {
const data = proxy.readQuery({
query: GET_BARS_QUERY,
variables: {
location: 'New York'
}
});
data.getBars = [result.userGoes, ...data.getBars];
proxy.writeQuery({ query: GET_BARS_QUERY, data,
variables: {
location: 'New York'
}
});
}
});

react-admin: changing a list from store without http requests

I am using react-admin and I need to control directly the store from one resource, in my case, the orders resource.
Everytime I run the GET_LISTit appends the new records in the list from the store, but, I would like to get a new list from the server and discard the old ones. Here`s where I retrieve the records:
dataProvider(GET_LIST, 'orders', {
filter: { updatedAt: filterDate }, // Get date from Filter.
sort: { field: 'updatedAt', order: 'DESC' },
pagination: { page: 1, perPage: 999 },
}).then(response => response.data)
So, I decided to manipulate the store directly and after some digging I saw this answer and this code from the source:
const dataReducer: Reducer<RecordSetWithDate> = (
previousState = initialState,
{ payload, meta }
) => {
if (meta && meta.optimistic) {
if (meta.fetch === UPDATE) {
const updatedRecord = {
...previousState[payload.id],
...payload.data,
};
return addRecords([updatedRecord], previousState);
}
if (meta.fetch === UPDATE_MANY) {
const updatedRecords = payload.ids.map(id => ({
...previousState[id],
...payload.data,
}));
return addRecords(updatedRecords, previousState);
}
if (meta.fetch === DELETE) {
return removeRecords([payload.id], previousState);
}
if (meta.fetch === DELETE_MANY) {
return removeRecords(payload.ids, previousState);
}
}
if (!meta || !meta.fetchResponse || meta.fetchStatus !== FETCH_END) {
return previousState;
}
switch (meta.fetchResponse) {
case GET_LIST:
case GET_MANY:
case GET_MANY_REFERENCE:
return addRecords(payload.data, previousState);
case GET_ONE:
case UPDATE:
case CREATE:
return addRecords([payload.data], previousState);
default:
return previousState;
}
};
So, based on that, I created a custom action to delete the old ids from my list and add the new ones retrieved from the data source:
import {GET_LIST, DELETE_MANY, FETCH_END } from 'react-admin';
export const UPDATE_ORDER_ADMIN = 'UPDATE_ORDER_ADMIN';
export const update_orders_admin = (data, oldIDS) => ({
type: UPDATE_ORDER_ADMIN,
payload: { data, ids: oldIDS },
meta: {
resource: 'orders',
optimistic: true,
fetch: DELETE_MANY,
fetchResponse: GET_LIST,
fetchStatus: FETCH_END,
},
});
And I am using this custom action after retrieve data from the backend:
dataProvider(GET_LIST, 'orders', {
filter: { updatedAt: filterDate }, // Get date from Filter.
sort: { field: 'updatedAt', order: 'DESC' },
pagination: { page: 1, perPage: 999 },
}).then(response => response.data)
.then(data => {
const ids = orders ? Object.keys(orders) : [];
update_orders_admin(data, ids);
this.setState({ isLoading: false })
return null;
});
However, the system is calling the DELETE action from backend, trying to delete the records from the database, while, what I would like is just delete these records from my view.
Any thoughts?
In your custom action you have the fetch set as DELETE_MANY which will do a loop over every id performing DELETE operation. Not sure if you implementation will work, but the current error is about that. You could try to remove the fetch ans see what happens, but I think without it he will not fetch records. If I'm not mistaken RA only adds new ids to data, however if data changed in the meantime I don't think it will replace the changed data for that you need to reimplement the data provider to change the update data behaviour which is similar to what you're trying.

How to make polling on react-table

I'm trying to build a React-Table which can make polling to a remote server every second to fetch newest data. I just followed what the author did in the doc (https://react-table.js.org/#/story/server-side-data) and tried integrate the polling function (setInterval) in "componentDidMount" but it FAILED.
The error message shows that when running "requestData" under "componentDidMount", "filtered" is undefined, whose length is not accessible. How can I fix that? Thank you.
import React from 'react';
import _ from 'lodash'
import ReactTable from "react-table";
import 'react-table/react-table.css'
const requestData = (pageSize, page, sorted, filtered) => {
return fetch(
'http://127.0.0.1:5000/agent',
{ method: 'GET'}
).then( res => res.json()
).then( filteredData => {
if (filtered.length) {
filteredData = filtered.reduce((filteredSoFar, nextFilter) => {
return filteredSoFar.filter(row => {
return (row[nextFilter.id] + "").includes(nextFilter.value);
});
}, filteredData);
}
const sortedData = _.orderBy(
filteredData,
sorted.map(sort => {
return row => {
if (row[sort.id] === null || row[sort.id] === undefined) {
return -Infinity;
}
return typeof row[sort.id] === "string"
? row[sort.id].toLowerCase()
: row[sort.id];
};
}),
sorted.map(d => (d.desc ? "desc" : "asc"))
);
const res = {
rows: sortedData.slice(pageSize * page, pageSize * page + pageSize),
pages: Math.ceil(filteredData.length / pageSize)
};
return res;
});
};
class AgentTable extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
pages: null,
// loading: true,
};
this.fetchData = this.fetchData.bind(this);
}
fetchData(state, instance) {
// this.setState({
// loading: true
// });
requestData(
state.pageSize,
state.page,
state.sorted,
state.filtered
).then(res => {
this.setState({
data: res.rows,
pages: res.pages,
// loading: false,
})
})
}
componentDidMount() {
setInterval(
() => requestData(
this.state.pageSize,
this.state.page,
this.state.sorted,
this.state.filtered
).then(res => {
this.setState({
data: res.rows,
pages: res.pages,
// loading: false,
})
}), 5000
);
}
render() {
const { data, pages, loading } = this.state;
return (
<div>
<ReactTable
columns={[
{
Header: "Agent ID",
accessor: "AGENTID"
},
{
Header: "Description",
accessor: "DESCRIPTION"
},
{
Header: "Domain",
accessor: "DOMAIN"
},
{
Header: "Register Time",
accessor: "REGTIME"
},
{
Header: "Status",
accessor: "STATUS"
},
]}
manual // Forces table not to paginate or sort automatically, so we can handle it server-side
data={data}
pages={pages} // Display the total number of pages
loading={loading} // Display the loading overlay when we need it
onFetchData={this.fetchData} // Request new data when things change
filterable
defaultPageSize={20}
className="-striped -highlight"
/>
</div>
);
}
}
export default AgentTable;
First off, you need to understand what the onFetchData callback is.
Taken from the docs, onFetchData is:
This function is called at componentDidMount and any time sorting, pagination or filterting is changed in the table
So what you're trying to achieve here won't work the way tried to.
Seeing as fetching data from a remote server every second isn't one of the conditions that invoke the onFetchData callback, you should try a different approach.
I forked React-Table's Simple Table example and added timed data requests here, this should help you get started.

Resources