You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 8, 2020. It is now read-only.
Repository navigation
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
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.
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 :)
@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.
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 :)
@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.
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!
@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?
Activity
parys commentedon Dec 10, 2016
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 commentedon Dec 10, 2016
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 commentedon Dec 13, 2016
@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 commentedon Dec 13, 2016
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 commentedon 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
httpcalls, 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 commentedon Dec 13, 2016
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 commentedon Dec 14, 2016
@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 commentedon Dec 14, 2016
Sure, done! (Issue here TrilonIO/aspnetcore-angular-universal#29)