Server-side rendering with Node/React. How do I fetch the data? - node.js

My goal is to server-side render my blog built with Node and React/Redux. I am following this tutorial, and using this project as an example.
I have loaded my components, created an empty store, successfully used this stuff to render and return html pages.
My remaining challenge is to figure out how to fetch the inital data so that I could put it into the store. I am assuming, I somehow need to tell the store(on the backend) to dispatch the actions that will fill it with data.
This example is using this function, that seems to be telling the store to dispatch actions, and returns the store filled with data(?). But it flies way over my head, I don't get how it works, and when I copy the code, the store still returns empty.
Can you help me to understand how this is supposed to work? What do I need to do to tell the store to execute actions, that will go to my API, fetch data, and put it into the store?

basically fetchComponentData will dispatch actions while server rendering, like the document says
fetchComponentData collects all the needs (need is an array of actions that are required to be dispatched before rendering the component) of components in the current route.
where need is an array of functions that return a redux action, which defined inside each smart components (connected with redux store and react-router)
for example, in mern-starter, when you visit index route, it'll render this component and there is the need method which will be executed by fetchComponentData when server rendering.

Related

Caching api response using react-query when changing routes but be able to receive data when reloading the page

I have prepared a simple demo with react-router-dom 6 and react query.
I have a couple of routes and a fetch call that takes place on the first route (Home).
What I want to achieve is navigating to the About page or any other page and do not perform another request for a certain time period (maybe never again) but if I refresh the page I want to be able to re trigger the request to get the data.
I have tried using staleTime when but if I refresh the page I get no results, just a blank page. refreshInterval works on refresh but does not keep the data when I change routes.
I have also tried this pattern in this article but still I don't get the job done.
Probably it may be that something I don't understand but the question is how do I avoid making the same request over and over again, perfrm it only once but still being able to get the data if I refresh the page when navigating between different routes.
Demo
The solution to the problem came from one of the maintainers on the official github repo eventually and is related to adding placeholderData as an empty array instead of initialData and setting staleTime to Infinity in my case as I only want to perform the request once.
Setting placeholderData gives you the opportunity to show some dummy data normally until you fetch the real but in my case it seems to do the job. More to read regarding this at this source
const { isFetching, data: catImages } = useQuery({
queryKey: ["catImages"],
queryFn: getCatImages,
placeholderData: [],
staleTime: Infinity
});

Angular/NodeJS - Mongoose Pagination

This is more a design question than a lot of code.
I have my angular client query a mongodb collection via http and nodejs backend.
I want to paginate the result, so what I do is on the angular side, keep track of the page I'm on and the # of results I would like on each page, and I pass that on to my backend via an http call.
Then my backend has code that looks something like this:
schema.find({name: query, _userId: req.body._userId}).sort({ name: 'asc' }).limit(req.body.num_results).skip(req.body.page * req.body.num_results).then(response => {
Now I'd like to put "<" and ">" arrows on my client's html where every time left or right is clicked it traverses pages (via a new http call), but then make it so that "<" is disabled on page 0, and ">" is disabled on the last page of results. I've figured out how to disable the "<" - simply make the button go away when you're on page 0. But having trouble figuring out the best way to discover that I'm on the last page. One method could be for my backend to return the total number of results and then my front-end tracks where I am relative to the total #, but that involved another db call, move variables passed over http, more management on the front-end. Any ideas on how to implement a 'cleaner' solution?
Thank you.
You do not need to make any additional api call. You can return any additional information in the form of Http header when making api call. so, in this case return X-TOTAL-COUNT

How can I avoid querying the same data twice when I require 2 http responses (one a file, one a json object)?

I have the following layout. If the Export to Excel checkbox is not checked, upon the button being pressed an API call will be made to query the data in the date range, and displayed in d3 graphs below. If it is checked, the button makes the same API call, in addition to referencing a 2nd call that downloads an Excel file. I think these 2 separate calls are necessary because I need the data in both forms (json and an attachment) which both require separate headers. I wasn't able to figure out a way to make just one call and return the data both ways, but if that's possible I would be open to that solution. Otherwise, what are my options to query the data just once, and share it between both calls?
A HTTP request can only respond with one response type. So with a single request you can only return json or excel (whatever encoding you used). When you click that button and the excel checkbox is checked, do you need both responses? Or just the file?
If you just want the file, then ignore the JSON and do not update your d3 graphs.
If you want the graphs and the file, you'll have to make two requests, one for the JSON and one for the file. If you want to only process that DB call once on the server, you'd need something else. Like, return the JSON data and store the file at a link you'll know the address to. Or return the file and push the JSON to the client (WebSocket or similar).
If you can cache on the server (caching DB like redis or in-memory if you can guarantee you'll hit the same server node), you could store/hash the query parameters with the returned data. Any future call would check that cache first and maybe not hit the DB. (Of course, be aware that if any data would update the results, you'll need to kill your cache key so the data is requeried).

Unobvious model change

In a angularjs/express/postgres app, i want to load big list of json object from the db to the client.
Each json object is it's self pretty big. Each on is stored in a separate row.
So i want to display each json object as soon as they are read from db.
I've found the EventSource api, to progressivly send the json object from server to client.
Which works fine.
Then i want to display them on my view as soon as possible.
Working with event source include working with event listeners.
As explain here https://groups.google.com/forum/?fromgroups=#!topic/angular/xMkm81VkR9w
the angular won't notice the change of the model since the scope modification occurs outside the angular world, inside a event listener.
There is a way to trigger to dirty cheking by calling $scope.$apply().
But since my list as more than 200 element, this error is triggered:
Error: 10 $digest() iterations reached. Aborting!
So i'm wondering if there is another way to trigger the dirty checking ? Maybe another way to approch my issue.
EDIT:
The title was changed after reflection on the real problem
In fact the issue come from the partial, where i add filter expression in a ng-show directive
My bad

JSF: How to capture response that is send to client

I want to implement some kind of help-functionality within my jsf-application
Scenario:
When the users of my app are having problems, they send me screenshots. These are of poor quality and I cannot see the information I want.
My idea: I add a "help"-Button into my jsf-Page. When this button is pressed I store the render-response (resulting html) that is send to client on my hd.
Now I can open that generated html-file and can see the information I want (e.g. values of inputfield)
Now my Question.
How can I perform this task?
I have tried PhaseListener and using
PrintWriter w = new PrintWriter(System.out);
DebugUtil.simplePrintTree(FacesContext.getCurrentInstance().getViewRoot(),"",w);
but this is just the component tree and not the resulting html
In other words: I want to capture the output of FacesContext.getExternalContext().getResponse() that is send to client
any ideas?
Use a Filter around the FacesServlet. There define a HttpServletResponseWrapper and in turn make its getOutputStream() and getWriter() return wrappers of the original objects. In the wrappers, in addition to delegating to the original implementation, store the written data somewhere else.

Resources