Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

Angular2Spa template: Server-side prerendering doesn't work properly #505

Closed
TarasBanakh opened this issue Dec 10, 2016 · 8 comments
Closed

Comments

@TarasBanakh
Copy link

TarasBanakh commented Dec 10, 2016

In Angular2Spa template:

Make the Web API method WeatherForecasts slower with System.Threading.Thread.Sleep(TimeSpan.FromSeconds(3));

Then when I navigate to 'Fetch data' page I can see a message "Loading..." which in this case means that the angular is performing an ajax request from browser to get data. But this page should have been prerendered on server!

Another strange thing with server-side prerendering is that when I refresh (F5) the 'Fetch data' page then the Web API method WeatherForecasts is called twice: once from server (when prerendering) and once from browser.

@parys
Copy link

parys commented Dec 10, 2016

method WeatherForecasts is called twice: once from server (when prerendering) and once from browser.

Once called for filling data for prerendering server page, and second for getting actual state for angular, because prerendering page is just a html.

@MarkPieszak
Copy link
Contributor

As parys stated, yes the first is a serialization of the application that happens to generate that initial string of HTML (that is your App at that view etc), then in the browser it has to bootstrap, since it's a single page application from then on after all.

Note: this process is a little bit involving.
So to avoid this for certain calls you're going to have to hook into a few things within universal,and you're also going to have to create 2 App.module.ts files, one for the browser, one for the server (as these are where the hooks are temporarily. If you look here you can see I have 2 of them, and a CacheService as well. (https://github.com/MarkPieszak/aspnetcore-angular2-universal/tree/master/Client/app/platform-modules) The important code is inside the Class of each NgModule as well. Then you need to make sure both boot-client and boot-server are using their correct NgModule.

After that, calls that you want to Not be re-ran on the client, simply need to use a special HttpCacheService like the one here, and this would instead grab that data right away, instead of going to the server again.
Demo useable here

Check out some more Universal/isomorphic gotchas here.

I know it seems like quite a bit, but it's not the simplest task sharing responses like that :)

@SteveSandersonMS
Copy link
Member

@MarkPieszak Thanks for answering!

@TarasBanakh Like Mark says, it is nontrivial to set up Angular 2 to preserve application state during the transfer from server to client. If this is really important to you, you might want to consider React+Redux instead, because it handles it completely transparently and automatically. See the React+Redux generator included in generator-aspnetcore-spa.

@MarkPieszak
Copy link
Contributor

It handles it in a similar way by placing it on the window and then getting the data from it as well doesn't it? I hope to get us on that level of automation sometime in the next few months. There's always room to improve :)

@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Dec 13, 2016

@MarkPieszak It's completely different, architecturally, because it's using Redux so there's a well-defined central store for all state.

I'm guessing your approach for Angular would be to cache the responses to http calls, which would work in terms of eliminating duplicated network calls, but wouldn't cause the client-side code to skip the process of rebuilding the app state (whereas with Redux, it really does skip all of that, both the network calls and the repeated processing of data, on the client). This HTTP-caching approach for Angular would be absolutely fine, though bears little resemblance to how React+Redux handles it.

@MarkPieszak
Copy link
Contributor

I have Angular2 with Redux (NgRx in our case) together, I think I see whta you mean. I'll have to try and integrate the 2 worlds to see if it's possible to handle it all in a similar way. SSR really makes things trickier doesn't it!

@TarasBanakh
Copy link
Author

@MarkPieszak That would be great! I think Angular has to catch up on this. Is it Ok for you to add it to roadmap of your aspnetcore-angular2-universal so we could follow the progress?

@MarkPieszak
Copy link
Contributor

Sure, done! (Issue here TrilonIO/aspnetcore-angular-universal#29)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants