My understanding (or misunderstanding): I've just started learning the mean stack and i see that a lot of tutorials (most are pretty old) and some template projects (like mean.io) using angular for routing instead of express (about 80% angular routing and 20% express). My understanding of angular routing is that it is suppose to ajax in a template into the ngView which would keep the page from reloading giving me a true single page application.
my setup: So i have express routing all request to the index file and from there i have created routes in angular for all possible request. each request is routed by angular to a jade template file (which i've seen called partials).
The issue: so i thought that angular would be ajaxing in the partial with each request (giving me the benefit of not having the whole page reload) making a true single page application, but what i've found is that because express (or any other web server for that matter) is routing all request to the index file so angular can do it's thing the index file is always reloaded with each request. because of this, I feel like the ajax routing is meaningless. After all, if the index file is always reloaded on each request which in turn reloads the angular files (and all the js and css files called in the head) then there is no real difference between angular routing and express routing coupled with jade template includes.
The question: Is this the way angular routing coupled with express is meant to be set up and suppose to function or am i doing it all wrong (or when using the mean stack, is it more of a personal choice as to which routing to use rather than a distinct advantage/dis-advantage)?
I see what is going on here: the ajax only seems to happen when following a link from within the browser. If you manually modify the url in the browser bar to test the link it will reload everything. Now i feel silly as hell.
Related
I've been studying the difference between single page apps and multi page apps, and I think I have good view how they differ. Single page app starts by loading a single html page, and then it does never again fully refresh the page or override the original, unless the application is otherwise refreshed (browser refresh etc.) For example, the angularJS seed project: angular-seed has an index.html file. This file is the single page, that the server would send to front-end, and after that, all the other (possible) pages will be send asynchronously under the hood by using AJAX. So if you create app just with the angularjs seed, it is always going to be just a SPA application, am I right?
How in practice would you then create a multipage application with angularjs? Wouldn't you need multiple angularJS applications then? Would you have to have a separate routing for each of those angularJS applications? And why would one want to make multipage application for angularJS? Because one could always use the first index.html just as a shell, without real content, and then have separate container-pages for different pages. Could it be said that angularJS multipage app would be an application, that would just contain many SPA angularJS applications? In SPA, can you use the browsers' back-button, in order to go back to last view?
Yes, you've got the idea of SPA and MPA right.
Angular.js enables you to create SPAs but does not force you. In an MPA, I would not speak of multiple Angular applications since you would have just spread Angular.js modules over multiple HTML pages. The page flow or routing logic would then be in Angular.js controllers, in plain hyperlinks or in the backend on the server.
There might be reasons to not put a whole application under Angular.js. Maybe the authentication part of a web application might be Held separately for some reasons...
In SPAs you definitely can use the browser's back button. You just have to implement that somehow. Twitter solves this Problem by coding the state of its web application into the URL - if you're using Twitter, you might have noticed the symbols (#!) in the address bar.
Non-SPA AJAX Partials for SEO
Sadly, 101% of the Angular SEO examples assume the use of a singe-page-application (SPA). My app is not a SPA. Currently, my stack is:
Node/Express - for routing and rendering Jade templates. The URLs are real, and don't use HTML pushstate, hash-bang or anything similar. for this reason, url-escaped-fragment won't work for me (I don't think)
Angular for communicating with my RESTful API(s)
My problem is that my page itself only includes pieces that are loaded via AJAX—the rest of page is rendered server side. Node/Express is not responsible for any of this logic, Angular pulls in the data that will be in my first h1.
Google Bot and similar see: <h1>{{this_unrendered_string}}</h1> which is no good.
Has anyone come up with any clever solutions for working around this scenario?
FWIW I found a service called SEO.js that will host a rendered version of any page I pass to it. If I could just tell GoogleBot and similar "Hey, don't use this page, use this page instead" But I'm not entirely sure how SEO feels about a different host serving content. Maybe some trickery could work here..
Google have documented an approach to "Making AJAX Applications Crawlable" here. https://developers.google.com/webmasters/ajax-crawling/
Implementing this isn't completely simple (basically you have to run a headless browser and return the HTML snapshots in response to specially formatted requests by Google).
It's not a simple as just returning a snapshot when you detect GoogleBot, but doing it this way probably eliminates any risk of being penalized.
There are a few companies that offer this a service - I'm getting on well with this one: https://ajaxsnapshots.com - they say that Bing and Yandex (Russian search engine) support it too.
AjaxSnapshots have an API you can use to tell them when your page is ready to snapshot - you could call that after all of your client side rendering is done.
I have been looking at Hulu's new website and I am very impressed from a developer's standpoint (as well as a designer's).
I have found that, unless you switch between http/https, you are served content entirely from json requests. That is a HUGE feat to have this level of ajax while maintaining browse back button support as well as allowing each url to be visited directly.
I want to create a website like this as a learning experience. Is there any type of framework out there that can give me this kind of support?
I was thinking I could...
leverage jQuery
use clientside MVVM frameworks like KnockoutJS?
use ASP.NET MVC content negotiation to serve html or json determined by an accept header.
using the same codebase.
use the same template for client side and server side rendering
provide ways to update pagetitle/meta tags/etc.
Ajax forms/widgets/etc would still be used, by I am thinking about page level ajax using json and client side templates.
What do you think? Any frameworks out there? Any patterns I could follow?
It is always best to first build a website without AJAX support, then add AJAX on top of that. Doing this means that:
users without javascript can already access your website
users can already visit any URL directly.
Adding AJAX support can be accomplished by various javascript libraries. So that you can render json content, you will want to look at javascript templating. You will want to use javascript templating even on your server side for when you add AJAX support (file extension .ejs). This will probably require some appropriate libraries to run javascript on the server.
When you add AJAX support, you will want to use the "History.js" library for browser back/forward/history support.
Make no mistake. This is a HUGE project (unless your website only has a few pages). So it is going to take a LONG time to add all the AJAX support to the best possible standard.
to answer your bullet point about using the same template server side as well as client side: check outdust. It was originally developed by akdubya, but has since been adopted and enhanced by linkedin. They use it to render templates on their mobile app client side. Personally I've used it on the server side and it works great.
I used to utilize MVC 3 Razor engine to render pages. Sometimes I had to use AJAX calls to transfer Razor-rendered HTML and inserting it into the page using JQuery. As new project is starting, we do consider to utilize MVC 4 Single Page Application framework which is new to us. I took the first glance at it which left me with mixed feelings:
On the one hand it implies all your data are transferred by JSON and client does all the job to render them and encode some UI-related logic which is great for server and network performance. On the other hand the client (HTML+JavaScript) becomes much more heavy with a bunch of magic strings and hidden relations inside it which seems to be hard to maintain. We got used to VS intellisense, type-safed .NET server code to render pages which we have to exchange for client scripts and Knockout binding statements in case of SPA.
I wonder are any prons and cons of using SPA comparing to Razor, other that this obvious one I've mentioned here? Thanks
Razor is a server based technology where SPA (Single Page Application) is an architecture approach used on the client (web browser). Both can be used together.
From a high level, SPA moves the rendering and data retrieval to the client. The web server becomes a services tier sitting in front of the database. An MVC pattern works best when using SPA. Frameworks like Knockout.js and Backbone.js can be used for this. The net results is a rich responsive desktop like experience.
To achieve this you'll need to be a descent javascript programmer or be willing to learn javascript.
Yes it's moving business requirements from C# into javascript. In Visual Studio there is limited intelli-sense for javascript. To have confidence in your javascript you'll need to lean on unit testing. The up side is the rich user experience (think gmail or google maps).
I think it sounds like you are already fairly well apprised of most of the trade-offs here; you'll have reduced network load with SPA, and will shift a measure of the processing to the client. You will, however, increase the complexity of your code, and make it slightly harder to easily maintain the system (simply because of the increased complexity - not due to any architectural problems inherent in SPA).
Another thing to keep in mind is compatibility. The reason I mentioned a "false choice" in my comment to your question is that to keep the site usable for folks with Javascript disabled, you will still need to provide regular, whole-page views. This is also a good idea to do for the sake of SEO; a crawler will browse your site as a user with JS disabled, and can then index your site. The site should then handle such incoming URLs properly so that those with JS enabled will find themselves in your SPA looking at the same content (as opposed to being dumped in the "no JS" view unnecessarily).
There's something else I'll mention as a possibility that might help with the above, but it breaks the ideals of an SPA; that is, using Ajax-loaded partials in some places, rather than JSON data. For example, say you have a typical "Contact EMail" form on the site; you want that to load within the context of the SPA, but it's probably easier to do so by loading the partial via AJAX. (Though certainly, yes; you could do it with a JSON object describing the fields to display in the e-mail form).
There will also likely be content that is more "content" than "data", which you may still wish to load via partials and Ajax.
An SPA is definitely an interesting project, and I'm about to deploy one myself. I've used a mix of JSON and partials in it, but that may not be your own choice.
I am currently designing an application that will have a few different pages, and each page will have components that update through AJAX. The layout is similar to the new Twitter design where 'Home', 'Discover', and 'Connect' are separate pages, but interacting within the page (such as clicking 'Followers' or 'Following') uses AJAX.
Since the design requires an initial page load with several components (in the context of Twitter: tweets, followers, following), each of which can be updated individually through AJAX, I thought it'd be best to have a default controller for serving pages, and other controllers with actions that, rather than serving full pages, strictly handle querying the database and returning JSON objects. This way, on initial page load several HMVC requests can be made to gather the data for each component, and AJAX calls can also be made to update each component individually.
My idea is to have a Controller_Default that handles serving pages. In the context of Twitter, Controller_Default would contain:
action_home()
action_connect()
action_discover()
I would then have other Controllers that don't deal with serving full pages, but rather components of pages. For instance, in the context of Twitter Controller_Tweet may have:
action_get()
which returns a JSON object containing tweets for a specific user. Action_home() could then make several HMVC requests to get the data for the several different components of the page (i.e. make requests to 'tweet/get', 'followers/get', 'following/get'). While on the page, however, AJAX calls could be made to the function specific controllers (i.e. 'tweet/get') to update the content.
My question: is this a good design? Does it make sense to have the pages served through a default controller, with page components served (in JSON format) through other function specific controllers?
If there is any confusion regarding the question please feel free to ask for clarification!
One of the strengths of the HMVC pattern is that employing this type of layered application doesn't lock you into a workflow that might be difficult to change later on.
From what you've indicated above, this would be perfectly acceptable as a way of serving content to a client; the default controller wraps sub-requests, which avoids multiple AJAX calls from the client to achieve the same goal.
Two suggestions I might make:
Ensure that your Twitter back-end requests are abstracted out and managed in a library to make the application DRY'er and easier to maintain.
Consider whether the default controller is making only the absolutely necessary calls on each request. Employ caching to avoid pulling infrequently changed data on every request (e.g., followers might only be updated every 30 seconds). This of course depends entirely on your application requirements, but if you get heavily loaded you could quickly find your Twitter API request limit being reached.
One final observation: if you do find the server is experiencing high load and Twitter API requests are taking a long time to return, consider provisioning another server and installing a copy of your application. You can then "point" sub-requests from the default gateway application to your second application server, which should help improve response times if the two servers are connected by a high-speed link.