Material-ui table pagination - reactjs

I am using Material-ui table for listing data. table will load all data at once from remote server. Is there any way to load data through pagination, as page changes data has to be fetched from remote.
when page loads i will get data from following code.
const options = { method: 'GET', headers: { Origin: '*' } };
fetch(`https://some-url/user_groups`, options)
.then(function (result) {
//i will get data here
})
.catch(error => console.log('error while fetching ', error));

Follow following steps:
Step 1. Change the server side to return only 1 page of data, and also return number of available records.
/api/getData?offset=5&limit=10
Step 2. On your react components, or redux store, create following state:
{
data: list of data item to display on the table
page: the current page of the table
resultCount: number of available records
}
Step 3. Implement loadData to load the current page of data & result count.
Step 4. On component mount & page change event, reload the data.

yes you can by adding condition to the pagination slicing logic
rows.slice((useDbPagination ? 0 : page) * rowsPerPage,
(useDbPagination ? 0 : page) * rowsPerPage + rowsPerPage).map(/*render row here*/);

Related

How to add URL args depending on content in NextJS React web app? [duplicate]

I am developing a ecommerce store using NEXT.JS and Redux. So in product listing page, I have sorting select dropdown with Price Low to High, Price High to Low and New Arrivals. Upon selecting this option, I want to change the URL without page refresh and API call should occure. I have tried using below code, but it is not working and page is reloading.
function sortBy(value) {
router.replace({
pathname: '/products/'+slug,
query: { sort: value }
})
dispatch(fetchproducts(slug, sort));
}
The above code just refresh the current page and appending sort param to URL.
So is it possible to do it without page refresh like in Flipkart.
With the help of shallow-routing change of URL without doing a page reload is possible. It can be enabled by passing explicit option object as third argument to Router.push, i.e { shallow: true }
From the docs
Shallow routing allows you to change the URL without running data fetching methods again, that includes getServerSideProps, getStaticProps, and getInitialProps.
You'll receive the updated pathname and the query via the router object (added by useRouter or withRouter), without losing state.
For example, this how you would update the query param sortBy for pathname /products with the help of shallow-routing.
Router.push({
pathname: '/products',
query: { sortBy: 'price' }
},
undefined, { shallow: true }
)
But there are a few caveats It is not possible to do shallow-routing between different pages, it works only for same page URL changes. See the caveat section for more details.
For example, you can update a query param for page /product page, but it won't be possible if you try to do shallow-routing from /product to /product/[slug] because they are two distinct pages.
// page will reload because shallow-routing not possible between the pages
Router.push('/product', '/product/some-product?sortBy=price', { shallow: true })
Example:
you have a folder like: posts/[id].js and your url is like http://something.com/posts/123
You want to add a query param that will not refresh the page and your url will be like: http://something.com/posts/123?param=ok
all you need to do is:
const postId = 123;
const param = 'ok';
router.push(
{
pathname: `/posts/[id]`,
query: {
postId,
param
}
},
`/posts/${postId}?param=${param}`,
{shallow: true}
);

Chrome and Edge hang on React page load for only some users, should I change my useEffect strategy?

My ReactJS project displays a simple page consisting of a header section with project title, version and a few nav links, then a table of about 200 results as the main content of the page.
The initial page loads for everyone and the components appear as expected, but on page load (I believe this is when the useEffect hook kicks in) some users report the page becoming un-responsive and no matter how long it is left, it never finishes. This has been reported in both Chrome and Edge by 5 different users across a site of 200+ users, the majority have no issues despite running the exact same hardware and connection.
On page load, I expect the title, version and table contents (plus a few other variables) to be populated and automatically updated since these are in state, and for most users, this works as expected.
Below is my useEffect()
useEffect(() => {
// Update all initial values
fetchLastUpdated();
fetchVersion();
fetchUsername();
fetchUpcomingFilterOptions();
fetchLongCustomerNames();
fetchConfigs();
fetchUpcomingResults() // This will be displayed as rows
const job = document.getElementById("job")
if ( !!job ) {
job.addEventListener("keyup", function(event) {
if (event.key === "Enter") {
submitForm()
}
});
}
// Find environment for API links: testing/pre-release, testing/QA, flx
const url = window.location.href
if ( url.includes('localhost') ) {
setEnvironment("testing/pre-release")
} else if ( url.includes('testing/pre-release') ) {
setEnvironment("testing/pre-release")
} else if ( url.includes('testing/QA') ) {
setEnvironment("testing/QA")
} else if ( url.includes('flx') ) {
setEnvironment("flx")
}
}, [])
Below an example of an API call from useEffect
const fetchConfigs = () => {
axios({
method: "get",
url: "http://myURL/" + environment + "/WITracker/public/api/myConfigs",
config: { headers: {
'Access-Control-Allow-Origin': '*',
"Content-Type": "multipart/form-data"
}}
})
.then(function (response) {
setConfigs(response.data);
})
.catch(function (response) {
console.log("Failed to fetch configs!");
addNotification("Unable to fetch configs", "Retry in progress...")
})
}
When remote accessing the users with troubles loading the page, I asked that they each try the alternative browser: Chrome -> Edge or Edge -> Chrome and in each case this resolved the issue. I found this strange as I would have expected the same browser to be causing the same behaviour each time across the users.
I would like to make sure that the page reliably loads for all users regardless of their browser preference. I'm at a bit of a loss trying to find out why only some users are getting unresponsive errors so any possible solutions or suggestions of what to try are welcome!
Possible workaround?
I'm not sure that I have set up my useEffect the correct way using best practices. I'm thinking of adding a slight delay to the API calls, since the page loads the components without issue, and once the delay is up, to synchronously make each of the calls, giving the browser more of a chance to process the smaller chunks of work rather than all at once... please can somebody let me know their thoughts on this?
e.g. Something similar to the below theory?
useEffect(async () => {
// Some delay here, with loading screen
wait(1000) //custom function to wait?
// ...then, update all initial values
await fetchLastUpdated();
await fetchVersion();
await fetchUsername();
await fetchUpcomingFilterOptions();
await fetchLongCustomerNames();
await fetchConfigs();
await fetchUpcomingResults()
...
Thanks in advance

Live search with pagination in React.js

I want to search in all pages, but my code only search in the current page.
For example I'm in the page 2/5 when I type the name of a tourist who is present in this page it shows me the data,
but when I type a tourist which is in the page 4/5 it not show me anything.
I'm using Laravel in backend.
Here's the backend code :
$tourists = Tourist::where('hotel_id', $request->hotel_id)->orderBy('created_at', 'DESC')->paginate(10);
return $toursits;
Frontend code :
this.state = {
activePage: 1,
tourists: []
}
async componentDidMount() {
await this.getTourists();
}
async getTourists() {
let response = await callApi('tourists/paginate', { page: this.state.activePage, hotel_id: this.context.hotel_id[0] });
this.setState({ tourists: response.data, perPage: response.meta.per_page, total: response.meta.total, lastPage: response.meta.last_page });
}
Render method:
{this.state.tourists
.filter(x => new RegExp (this.state.first_name, 'i').test(x.first_name)
.map((tourist, i) =>
<tr>
<td>{tourist.first_name}</td>
</tr>)}
You are getting a paginated list of results from the backend but you are implementing the search functionality on the frontend.
When you first go to your page, you get the first 10 results from your server. At the time, your React application as no idea that there are more results to be parsed and can only "see" the 10 paginated results your are sending from your server. By filtering these results you will not be able to get any other result which was not sent by the server in the first place.
You have 2 solutions:
Implement the pagination client-side,
Implement the search functionality server-side
Given that you already implemented pagination on the server I assume that you have a lot of results and that sending all of them at once would not be practical.
This leaves us with option n°2. Adding to your code example, you could do something like:
$tourists = Tourist::where('hotel_id', $request->hotel_id)
// Add this to filter results by first_name
->where('first_name', 'like', "%{$request->first_name}%"))
->orderBy('created_at', 'DESC')->paginate(10);
return $tourists;

React JS error "Cannot read property '0' of undefined"

I'm attempting to populate a drop-down box with data consumed from an API; The data in this drop-down box is reflected according to data populated from another drop-down box.
This is my code and where the error occurs:
fetchSimulation(building) {
const bearerToken = this.getToken();
fetch(`http://www.myAPI.com/${param.data}`, {method: 'GET',headers: {
'Content-type': 'application/json',
'Authorization': `Bearer ${bearerToken}`
},}).then(results => results.json()).then(simulation => {
this.setState({ segments: simulation.segments, selected: simulation.segments[0].segmentName })
this.props.onSelect(simulation.segments[0])
});
}
Error line:
this.setState({ segments: simulation.segments, selected: simulation.segments[0].segmentName })
this.props.onSelect(simulation.segments[0])
I have two questions:
Question 1: Could there be a syntax issue in the approach am using to pass parameters via the URL in my Fetch?
Question 2: The server my API is hosted on, I also notice that it constantly crashes / go down for about 25-40 minutes and then it's back up. I notice this occurs 3-4 minutes after running my APP. I'm very new to React JS, but could my code be cause of the server going down (is it possible, for example memory leak)?

Apollo Client cache

I just started using apollo client on a React application and I'm stuck on caching.
I have a home page with a list of products where I do a query to get the id and name of those products and a product page where I do query for the ID, name, description and image.
I would like that if a user visits the home page fist then a specific product page to only do a query for that product's description and image, also display the name during the loading (since I should have cached it already).
I followed "Controlling the Store" part of the documentation (http://dev.apollodata.com/react/cache-updates.html) but still couldn't resolve it.
The query that is done when we go to the product page still asks for both the product's id and name whereas they should be cached since I already asked for them.
I think I'm missing something but I can't figure it out.
Here is a bit of the code:
// Create the apollo graphql client.
const apolloClient = new ApolloClient({
networkInterface: createNetworkInterface({
uri: `${process.env.GRAPHQL_ENDPOINT}`
}),
queryTransformer: addTypename,
dataIdFromObject: (result) => {
if (result.id && result.__typename) {
console.log(result.id, result.__typename); //can see this on console, seems okey
return result.__typename + result.id;
}
// Make sure to return null if this object doesn't have an ID
return null;
},
});
// home page query
// return an array of objects (Product)
export default graphql(gql`
query ProductsQuery {
products {
id, name
}
}
`)(Home);
//product page query
//return an object (Product)
export default graphql(gql`
query ProductQuery($productId: ID!) {
product(id: $productId) {
id, name, description, image
}
}
`,{
options: props => ({ variables: { productId: props.params.id } }),
props: ({ data: { loading, product } }) => ({
loading,
product,})
})(Product);
And my console output:
The answer to your question actually has two parts:
The client cannot actually tell for sure that these queries resolve to the same object in the cache, because they have a different path. One starts with products, the other with product. There's an open PR for client-side resolvers, which will let you give the client hints about where to find things in the cache, even if you haven't explicitly queried for them. I expect that we will publish that feature within a week or two.
Even with client-side resolvers, Apollo Client won't do exactly what you described above, because Apollo Client no longer does query diffing since version 0.5. Instead, all queries are fully static now. That means even if your query is in the cache partially, the full query will be sent to the server. This has a number of advantages that are laid out in this blog post.
You will still be able to display the part that's in the cache first, by setting returnPartialData: true in the options.
This question is quite old, however, there is a solution to map the query to the correct location using cacheRedirects
In my project, I have a projects query and a project query.
I can make a cacheRedirect like below:
const client = new ApolloClient({
uri: "http://localhost:3000/graphql",
request: async (operation) => {
const token = await localStorage.getItem('authToken');
operation.setContext({
headers: {
authorization: token
}
});
},
cacheRedirects: {
Query: {
project: (_, { id }, { getCacheKey }) => getCacheKey({ id, __typename: 'Project' })
}
}
});
Then when I load my dashboard, there is 1 query which gets projects. And then when navigating to a single project. No network request is made because it's reading from the cache 🎉
Read the full documentation on Cache Redirects

Resources