Reputation: 210
I created a search function using react js to filter a table of data fetched from graphql endpoint code :
const SearchRes = () => {
let filtredRes = data.Orders.edges
.filter(item => item.node.shippingAddress.name === (query));
let res = filtredRes.length === 0 ? data.Orders.edges : filtredRes;
return res;
}
then t just do the following to get the data :
SearchRes.map(...)
this works fine and i could do the search but when i implemented graphql pagination , the search stopped working on the results , it only works before clicking a button to get more results
code :
import React, { useState, useEffect } from 'react'
import { gql, useQuery } from '@apollo/client';
import Table from 'react-bootstrap/Table'
import Moment from 'react-moment';
import moment from "moment";
import { Link } from 'react-router-dom';
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import { DangerousChangeType } from 'graphql';
import Search from './Search'
import Button from 'react-bootstrap/Button'
const GET_All_Orders = gql`
query Orders($input1: PaginationInput) {
Orders(input: $input1){
pageInfo {
hasNextPage
hasPreviousPage
}
edges{
cursor
node {
id
closed
email
createdAt
updatedAt
cancelledAt
displayFinancialStatus
displayFulfillmentStatus
lineItems{
edges{
node {
customAttributes{
key
value
}
id
quantity
title
variant{
id
image {
altText
id
src
}
title
weight
weightUnit
price
}
}
}
}
shippingAddress {
name
}
phone
subtotalPrice
totalPrice
totalRefunded
totalTax
processedAt
}
}
}
}
`;
export default function AllOrders({ input1 }) {
const { loading, error, data , fetchMore} = useQuery(
GET_All_Orders,
{
variables: {
"input1": {
"num": 20,
}
},
}
);
let date = new Date();
const [query, setQuery] = useState('');
if (loading) return <h4>読み込み中...</h4>;
if (error) return `Error! ${error}`;
const SearchRes = () => {
let filtredRes = data.Orders.edges
.filter(
item => (
item.node.shippingAddress.name === (query) ||
item.node.email === (query)
)
);
let res = filtredRes.length === 0 ? data.Orders.edges : filtredRes;
return res;
}
return (
<div>
<Row >
<Col xs={10}> <h5>すべての注文</h5></Col>
<Col><h5> 日付 : <Moment format="YYYY/MM/DD">
{ date}
</Moment> </h5></Col>
</Row>
<br/>
<Search getQuery={(q) => setQuery(q)} />
<br/>
<Table responsive hover size="sm">
<thead>
<tr>
<th className="allOrders">注文日</th>
<th className="allOrders">名前</th>
<th className="allOrders">注文者メールアドレス</th>
<th className="allOrders" >配送状態</th>
<th className="allOrders" >支払状況</th>
<th className="allOrders" >合計金額</th>
<th className="allOrders" >詳細</th>
</tr>
</thead>
<tbody>
{SearchRes().map(({ edges ,node :{id , createdAt , displayFulfillmentStatus , displayFinancialStatus , totalPrice , email , shippingAddress: {
name
} }}) => (
<tr key={id}>
<td> <Moment format="YYYY/MM/DD">
{createdAt}
</Moment></td>
<td>{ name} </td>
<td>{ email} </td>
{displayFulfillmentStatus == "FULFILLED" ? <td className="success">配送済み</td> : <td className="failed">未配送</td>}
{displayFinancialStatus == "PAID" ? <td>支払済み</td> : <td>未払い</td> }
<td>{totalPrice} </td>
<td>
<Link to={`/orders/${id}`} className="btn btn-light">
詳細
</Link></td>
</tr>
))}
</tbody>
</Table>
{/* button responsible for the pagination */}
<div className="text-center">
<Button
variant="light"
onClick={() => {
fetchMore({
variables: {
"input1": {
"num": 20,
"cursor": data.Orders.edges[data.Orders.edges.length - 1].cursor
}
},
updateQuery: (prevResult, { fetchMoreResult }) => {
fetchMoreResult.Orders.edges = [
...prevResult.Orders.edges,
...fetchMoreResult.Orders.edges
];
return fetchMoreResult;
}
});
}}
>
もっと
</Button>
</div>
</div>
);
}
maybe the issue is :
1 ) i think the problem is because the button fetch a different table maybe that's why the function doesn't search it .
Upvotes: 1
Views: 569
Reputation: 8962
I would say you are clearly missing an offset in your query. In your fetchMore
query, you still pass num: 20
as a variable, when in your own words
maybe because of the num variable because it is like the first parameter in graphql , you should specify how many result you should get so when i write "num": 20 in the button it will always return the first 20 result not the results after the cursor
Yes, so you will always get the first 20 results, no matter how often you fetch. I don't know your backend implementation, but basically the offset
is the parameter from which the results should start returning, so if you pass offset: 10, num: 5
, you should get the items 11 - 15.
So in order for your query to work, it should look like this:
query Orders($input1: PaginationInput, offset: Int) {
Upvotes: 1
Reputation: 1038
I think the SearchRes
function should be
const SearchRes = () => {
let filtredRes = data.Orders.edges
.filter(item => item.node.shippingAddress.name === (query) ||
item.node.email === (query));
let res = query ? filtredRes : data.Orders.edges;
return res;
}
When query is empty, which means the user let the search input empty, all result should be showed, and when the user enter something in the search input, only the filtered result should be showed, even if there is nothing matched. I don't know whether its the real reason of your bug, but I think it's really a bug.
Upvotes: 0