Server side state changes in Nuxt are disappearing on render - javascript

I'm trying to wrap my head around this problem I'm having. Let me break it down for you.
I have a Nuxt project, which utilizes a modular store.
I have a global middleware that only runs server side (meaning when the page is refreshed).
This middleware is used to check if there's a cookie with user data, if so I'm making a post request to Firebase to evaluate the refresh token and fetch the user meta information (such as display name, etc). (I also tried using NuxtServerInit, I get the exact same problem)
All of this works perfectly. It runs just fine and by logging everything I know it is working and the state is changed.
In a loginUser() method, it sets the state of the application. (A token and display name value). When I login through the web app itself the cookie gets set properly and the state as well. The token is stored there and the display name as well.
However if I refresh my page it goes through the middleware and sets the state, but then on render it seems to be discarding all these changes I made to the store on server side and resets the store ready to be used on the client side.
Am I missing a nuxt configuration here? Do I have to setup a specific key to tell nuxt to preserve the server side rendered store?
Does anybody have any experience with this happening? If so please point me in the right direction.

If, like me, you are doing something with the component in which your props for the state are programmatic whilst on the server, but get set as a component element on the client, then you should check whether they are set as props or as attributes on the client side. I think that, as it is rendered on the server, the attributes can be interpreted as props, but as they settle in the frontend, they become unreadable, and so the state disappears. This leads to the effect of seeing the page look correctly rendered for a split-second, only to then rerender without the correct state.

Related

Next.js fetch a token from an api on initial render and store it

I'm building an application using next.js, there is a need to fetch a guest token from an api and set in the cookie as it would be needed throughout the application. So the first thing I want is the token to be set in the cookie before any page is loaded.
I'm migrating from react, there this logic was there in the app.js file and it was a single page application.
I tried putting the logic in getServerSideProps in the home page, it worked fine and the cookie was set, but the issue was if the user go to any other page first directly, the cookie won't be there. To achieve that we have to duplicate this code in that page as well. (which I don't want as there are lot of pages)
Then on further research, I came to know that we can use getInitialProps in the _app file, that fetches the initial data for all the pages but it comes with a warning (This disables the ability to perform automatic static optimization, causing every page in your app to be server-side rendered.) Not sure if it would be ideal for this case.
Is there any other solution, like some kind of wrapper we can use on top of _app to fetch the token server side and store it.
I'm new to next.js, please help me with this.
If you want to share the same server side logic to all the pages you could use next middleware or next custom server.
Consider that middleware use a subset of the nodejs runtime features so to perform http request you have to use the custom server. AIf you want you can then left to the middleware just the set/check of the cookies.

Updating localStorage when there's new data from server?

After logging into an app (React.js), I am caching the member data in localStorage as a lot of my components are using it and request only needs to be done upon log-in, ideally.
However, a few properties in this member object may be changed in the backend manually so the frontend doesn't have a way to know whether the member object has changed at all. (Again, ideally, any change to the member object should go through some form submission that directly changes the DB, with which an update can be triggered for the localStorage, but this is not an option at this time.)
Example scenario: There's a generic form in the app to request for additional credits. Customer service will receive an email regarding the request. Credits would be manually updated for Customer A (in DB). If Customer A doesn't re-login (where the get request for member is done), localStorage will still show the old no. of credits.
If this is the situation, what's the best way to go about it?
Don't store member data in localStorage at all so as to keep the data fresh. Just call the endpoint whenever it's needed.
Use sessionStorage instead?
Trigger a refetch when the user refreshes the page / app (although user may not know that they need to do this to update the data).
Suggestions?
Calling the endpoint whenever its needed is ideal if the data is going to change based on things outside of the user's control.
Session Storage is just local storage that gets wiped when the browsing session ends, you'll still have the exact same issue
This doesn't really solve the problem, and it's typically a bad user experience to require the user to perform regular maintenance tasks in order to use your application to the best of its ability
I'd go with just getting the data fresh.
At a high level, you have two choices:
Poll (periodically call the back end to refresh the data)
Open a persistent connection (like a web socket) to the server, and have the server push updates to clients.
The latter option would require a lot of changes, and it changes the scalability of your app, so the former choice seems like the most reasonable option for you.
It's smart to keep using localStorage so you have an offline copy of the data and aren't blocking rendering during page load; you can have a background periodic refresh process that doesn't disrupt the user in the meantime. If your data is mirrored in something like redux or context, then your UI could seemlessly update if/when the data changes.
If you do not know when member has been updated, don't store it. You should query the back end every time you need member. That is the only way to keep the data sync with your database.

can users bypass restrictions to certain routes or pages in a vue.js application since all the code is rendered on the client side?

when building single page app with, for example, firebase, are the api keys used, not visible to the user since all the code is rendered on the client side? And also,since user is restricted to which routes or pages they can visit depending on the conditions set in the code, is it not possible for them to bypass or change the code since everything is on the client side?
Although it is correct that the code is client-side in an SPA, restrictions for accessing pages can still be set in place.
VueJS exposes several lifecycle hooks even before elements have been added to the DOM. In this space, you can make a network request to an authentication service. In your request, you would send a token (rf: jwt).
await the response and you can redirect users to the login page, or continue with the component mount.

Flux initializing stores on reroute

So I've been getting in to Flux the last couple of days, and more specifically I have chosen the alt flux implementation to work around. Mostly because of they way it handles server side rendering, which I thought was very nice. I am also using React Router (1.0.0-beta3 for now)
I have a problem with where to initialize my stores with data. My application uses server side rendering, thus I can fetch initial data from the API when a request comes to my server, and depending on the path that the user has entered I can fetch different data. (Is this correct? Seems kinda odd to me, since the purpose of SSR is avoiding the "blank white screen" but now we have to wait for async callbacks before sending back the server rendered DOM?)
But what if my user clicks on the Navbar for example, changing the path in react router? How do I initialize a store with new appropriate data now? If i understand everything correctly, this will not trigger another request from the server. It will simply rerender on the client using the bundled javascript. What do I do in this situation?
Say for example that I have a ProjectsStore that on /projects contains all projects that a company has ever done, but on /company/projects it only contains the projects for that specific company. How would I go about changing the data in this store?

AngualrJS: sustaining data on html refresh

is there any way in which i can load few data into some cache in angular js and onrefresh of the page load these datas from cache and display it again?
Right now issue is whenever i refresh the page, the details which were shared by the sharedServices app gets reinitiated since all the JS are reloaded on refresh of a page.
I have a Login page and a home page. On success of Login, using $route i am routing to the home page and broadcasting the loginID to the Homepage controller. now when i refresh this home page or copy the url and paste in another tab, i want the same data to exist. But in my case since the htmls/javascripts are getting reloaded it getting initialized to null.
Any angular technique available here?
Take a look at this discussion.
For small amounts of data (<= 4k) you can use $cookieStore, but after that you'll need to look into localStorage, keeping in mind that localStorage ties your app to HTML5 compliant browsers.
If you don't mind a little state on your backend, that's an option as well.
EDIT based on first comment
It sounds like your goal is that when the user hits refresh, the page should look as though they never hit it. You'd have to persist your entire application state to localStorage (scope, DOM properties, stateful services) ANY time these change. Not sure this is advisable.
You can get close enough to be functional, though:
To expand upon the answer from above:
Use the URL to describe application state, using Angular's $route service. I've always liked this article to explain URL and state, although the article is pretty Ember-specific.
As far as stopping the client from reloading your scripts upon refresh there is no way to do that - the closest you'll come is having your server return a 304 (Not Modified) code for those scripts.
Scope data and service state would have to persisted in local storage as described above.
Although the refresh problem is annoying it actually forces you to think as statelessly as possible, and stateless code is much easier to maintain and test. In case you were looking for an upside :)

Categories

Resources