I have a multi-page form spanning over several routes. All of the routes need the same data shared with them from an API. I can store the response of the API inside ngrx/store and trigger the API call using an effect. My question is more about where to initiate the API call. The API call needs to be made once the user is authenticated, which happens on the very first route I hit (before the first part of the multi page form is visited). The two options I've come up with are:
Triggering the effect inside each route's component meaning I'll just have to request the information every time I visit a route. A guard will prevent all pages being accessible while the user isn't authenticated.
Listen to the authenticated success action inside an effect and make the request to the API there.
I'm sure both are perfectly acceptable and have their trade offs. It'd just be good to get a few opinions!
The second would be the best, requesting the information on demand ergo when the user is authentified and its allowed to use it makes more sense. Inside of the guard, as u said, you should dispatch the action to load the information before you return true/of(true) to signalize that the route can be activated. The naive approach for this would trigger an information request everythime that you try to activate the guarded route.
Related
I have a React/React-Router application that is required to know the context on how users landed on the page. There could be two different cases (1) 302 redirection (2) client-side redirection.
Let me add use cases to give more details around it
(1): users directly hits the URL and landed on a page
(2): Users clicked a button and are redirected to another page via Link API.
I noticed that the react router props contains history object and on (1) case, the history action is POP while on client-side redirection cases (2) it was either PUSH or REPLACE. Would it be a good assumption that I can honor the history action and determine 302 redirection by checking the action === POP?
to suit your particular your use case there are multiple approaches on how we can achieve this let's go over a few you referred to in question
User clicks on a button: so if we have full control over the functionality of a button we can define multiple parameters if a user clicks on it e.g. we can add a query parameter on the forwarding url and on the next page we know where the user came from kinda like this www.example.com/?referrer=oldButton this would indicate clear patterns on how a user came to the page. or in terms of react router, we can pass additional params to access later on another component.
history.push('/path', yourData);
users directly hits the URL and landed on a page: you assumed correct we can use POP, PUSH, REPLACE methods to identify how the user came to land on a specific page. a browser use what we call history, it keeps a record of every page visited before or after another, we can either use it directly or through react-router
Hope that helped :)
Overview:
I got this route in my react application
example.com/routeName/:id
This is the entrypoint for my users, they click on the link and see a screen with informations provided by this hash in a right sidebar component.
example.com/routeName/94a31bb9-e6ae-4e9a-8749-0807f9efd0001
Below I attached a kind of wireframe, trying to be more clear about the sidebar:
Wireframe to understand how my app components are shown at the end, and why the hash is important in a visual way
This works fine, I can get the hash and make the request inside my dumb component to display data.
The problem:
I'm doing the fetch to the api in my Layout component, and passing down the data via props to my sidebar that is fixed in my layout, because it is displayed through all the user experience
When my user sign in, my route change, from:
example.com/routeName/94a31bb9-e6ae-4e9a-8749-0807f9efd0001
to:
example.com/nextRouteNameHere
I still see the component with the information I need, but if I refresh the page at the second route, the app crashes, because my sidebar cant find the hash to fetch my api and get the necessary data.
What I've been trying to do:
Persist this route with the hash and make the route change internally - but that doesn't makes sense to me at all, and I could not find any resources even close to this strategy.
Persist this hash in localstorage and get the hash with hooks inside the sidebar. This way if I can't find my hash at the url it'll be in the localstorage and I can fetch my api to get the data. I did it, but doesn't work because the components presents the some behavior, trying to render with no data.
As I'm using redux to manage the global state I've already taken the hash and the fetch response to the localstorage, this way I can take this data through all the aplication, but the hash is what makes my hooks update when I tried to wrote this strategy, and when the user updates the page I got the same behavior, because the hook could not find the :id on the url.
Final question
How can I persist the sidebar with the fetched data I did when I load the page?
NOTE
I did not post the code because at this moment I got too much code trying to solve this and I'm stuck in this problem for almost one month. I'll update this post later on.
On page load, say for a particular route for (e.g. https://localhost:8000/home/index), a service is called and the response from the service is rendered to the page at the client side.
On the same page, I have a link that pops up a Backbone.js modal and from the modal a click event triggers which hits another url (e.g. https://localhost:8000/home/index2) upon which another service call triggers and the response is rendered to another html page.
On the same html page, I want to display a value which I got from the first service call on page load. However, I am unable to retain that value as there are two different requests each time. Hence, I cannot even append the value from first response to the request object and use it a second time.
You can use JavaScripts Web Storage API to storage information on client browser.
MDN Web Storage API
For example, If you are on the first screen and call a service, store the service information on localStorage
localStorage.setItem('firstService', serviceResponseObject);
Once you are navigated to second page, you can use localStorage to read to previous service information
localStorage.getItem('firstService');
There are multiple ways to store state between requests.
From the server, if you're using say Express etc, you could store the result in a Session. Or you can even store state in the requests query params, or from a POST request.
You could also store some data on the client end, using say Cookies or localstorage.
What you choose really depends, it might be best if you explain in more detail what sort of information your passing between pages.
If it's just a simple value, I would go for using query params.
eg. Just place in your url https://localhost:8000/home/index2?value=123, and then from node.js, req.query.value would have your value.
I need input from someone experienced with React+Flux+async API requests pattern. What will be the better way to cache api response in the following situation:
I have 3 lists pages of articles each with corresponding API endpoint to fetch data.
each article has details page UI but there's no articleById endpoint, so I just .find necessary article by id in the fetched array
I want to make only 1 request on the list and cache it, so when I go to the details page from the list or return back to the list there will be no API requests.
When I switch to another list I should make the request and cache it.
I'm wondering should I cache the response in WebAPIUtils service which makes actual requests?
Or is it better to hack container component (which is the same for all 3 lists) in a way to know whether it should fire action which starts API request?
Thanks!
Using Stores
You should have ListStore that caches the lists that handles the following action:
LIST_CACHE : this action pushes a List to the List cache.
In your List component, when it receives an update from the ListStore, try to find the List that it's supposed to display and set that in its state.
If the list isn't there, wait for the ListStore to emit a change event, then in the ListStoreChanged handler, try to find the list again.
Now you need to decide on when to make the API request for the list cache. One possible option is making the API request for all the lists when your app loads, and then dispatching all the received Lists to the LIST_CACHE action.
If you haven't already, read this: http://facebook.github.io/flux/docs/overview.html
I'm wanting to make a 'before' hook for a certain page that will see if a user is signed in first and if not render/redirect to the sign-in page... now, should I use redirect or render for this?
I know this question is probably a more general question but I guess it would be helpful to know the difference between the two and when to use them..
The basic difference is that render will simply render the passed in template for whatever route the user landed on when the before hook was called, and redirect will change the route and render the template associated with the new route.
You can use either...just depends on what you want to accomplish. Sometimes you might want to allow the user to sign in from any page and then stay on that page...so, you would use a render. Other times, you want to send them to a sign-in route and then direct them to specific route following a successful sign-in...in that case, you'd perform a redirect.
Clear as mud?