Understanding AngularJS 2 vs AngularJS 1: Part 1

As I’m sure you know if you are reading this, the AngularJS team is planning for a major version release “very soon” that will include some major paradigm shifts. A lot of the things you learned while teaching yourself AngularJS 1.x will just not be present in AngularJS 2.

AngularJS 1.x is stable and will definitely be around for a long while with long term support from the original team. But do you really want to pass up on some of those amazing features (3-5x Performance increases, the ability to use Server Side Rendering, bragging rights)? No, of course not.

Just to make sure we can explain the concepts of Angular 2, let’s briefly review the main concepts of Angular 1.

Modules & Controllers

Controllers are just Javascript objects that create scope (more on this later), setting up attributes and functions. It’s the connection point for all scopes, functions and data sources in the application. These are similar to traffic cops that direct the flow and send data back and forth between the parts of your application.

A module can be thought of as the container that holds all the different parts of your AngularJS application. These have the advantage of making your code declarative and well encapsulated.

Directives

Custom HTML elements used to enable and interact with AngularJS. This cool feature is how we instantiate your app (`ng-app`) or create custom elements that transform data and views with JS logic stored in your models and controllers.

Here is an example of a directive in AngularJS 1.3 that replaced a `<burrito />` directive with an image of a burrito:

HTML

   <div>
<burrito></burrito>
</div>

JS

var app = angular.module(‘plunker’, []);

app.controller(‘MainCtrl’, function($scope) { });

app.directive(‘burrito’, function(){
return {
restrict: ‘E’,
replace: true,
scope: true,
template: ’<img src=“[ASSET SOURCE]” />’
};
});

Scope

The Application model and context, defined by an angular element. Defined hierarchically, scopes can be passed between elements

It’s important to note that Controllers, Services and Directives all have their own nested scopes. This can get messy when you are passing around data and need to make sure you aren’t polluting your own scope.

image

 

Databinding

 

While this is a great feature, it’s incredibly slow. Every digest cycle has to check ALL of these variables and update them appropriately.

Data binding is that magic that lets you sync data between your models and your view. In a sentence: your model’s data is bound to the view and your view is bound to your model’s data.

Here is a quick example:

HTML

<fieldset
<h1>Hello {{name}}!</h1>

<fieldset>

<label>an example of databinding:</label>

<br>

<input type=“text” ng-model=“name” />

JS

var app = angular.module(‘plunker’, []);app.controller(‘MainCtrl’, function($scope) {
$scope.name = ‘World’;
});

This is that awesome thing that does that sweet ‘live’ updating of values in your forms. Most likely, this was the huge selling point when you first started learning about AngularJS and the ‘reactive’ web.


We’ll explore where these things start to differ in Angular 2 in our next post

jQuery getSelector Plugin

jQuery getSelector Plugin

AngularJS JSONP GET Example

AngularJS JSONP GET Example

This is an example of a cross domain GET request using JSONP, the most common way to get data. Like the previous example using CORS, this too uses requires the server to be ‘aware’ of request so it can reply with the JSONP callback method.

The “P” in the JSONP actually stands for padding, which really means “Named Function”. You pass along a named javascript function that tells the server to wrap its response and when it responds your data is neatly wrapped with a helper function. This gets around the Same Origin Policy since <script> tags are ok’d for cross domain execution, which is how we can include JS libs from CDNs and other sources.

This method does require control over the request destination, or the site itself has to support a JSONP callback. This is just a javascript function returned from a ‘black box’, so there are some serious security concerns (but you’re not sending sensitive data via GET, right?). Also, we should note that this method have VERY limited support for reporting errors. Most people work around this by timing a response check and timeouts (which someday we may blog about).

AngularJS CORS example using httpbin.org

AngularJS CORS example using httpbin.org

This is an example of a cross domain GET and POST request to a server with CORS headers enabled. It’s a very simple one field form that displays the echo’d response from httpbin. I chose httpbin since I knew it had CORS headers enabled, and seemed like a relatively simplistic tool to play around with.

As the code shows, GET requests are quite simple and look like a regular $http call. The heavy lifting is all done by the server

The POST request on the other hand is a little more complicated and requires some manipulation of the headers before the request itself.

First, we need to set the Content-Type to form-urlencoded to let the destination know we are posting form data:

$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";

Second, we need to delete a header called “Requested-With” that is sent along with AJAX requests:

delete $http.defaults.headers.common['X-Requested-With'];

Also, to stop this mistruth from spreading any farther: A lot of blog posts about Cross Domain posting with Angular will show you this code:

$http.defaults.useXDomain = true

It’s not a real config value, you don’t need it. Seriously. Try it with and later without it, you won’t see a difference (I think the dojo toolkit may require it, I’m not sure how it made it’s way into multiple AngularJS examples).

Cross Domain AJAX & AngularJS: The Same Origin Policy

We are big fans of AngularJS here at Arroyo Labs, and often our Angular Apps require a lot of AJAX to work: a simple GET request to load data here, a form POST there. You know, typical web stuff.

More than once we’ve made an App that needs to make an AJAX request to a different domain than the one our app lives on and hit some roadblocks. For one, your browser doesn’t really allow it (I’ll explain this later) and for the most part it’s a pain compared to hitting a local resource.

“Why would you need to do that? Why aren’t you making locally hosted APIs to access this data?!” you may blurt out while reading this. Well sometimes, you have to.

Sometimes you run into a weird legacy architecture or you can’t access the backend code. You may even want to do all of this work with only front-end level code. What if you need the client’s browser to resolve a domain for you? It’s also possible you have been making AJAX requests to other domains and never encountered an issue until now.

The point is, eventually you will have to make an AJAX request on another domain, so lets talk about it.

The Same Origin Policy

The Same Origin Policy is a security feature built into your browser (and most everybody else’s) for your safety. It prevents scripts from accessing anything outside of the current ‘site’ as the executed script, and by site I mean the same Scheme + Hostname + Port as the page executing the script.

Take a look at this chart from the wikipedia page, for a script executing from http://www.example.com/dir/page.html

image

You can’t even make a request to a subdomain like http://foobar.example.com without Same Origin stepping in and waving its finger in your face. Try it, and check your console log: “not allowed by Access-Control-Allow-Origin" all over the place.

Why does this policy exist? Imagine an internet where we could access any domain’s HTML or make a POST ‘on your behalf’ (to websites you are logged into like your bank or twitter) from your browser with Javascript. Thats a scary place.

So, how do we get around the Same Origin Policy?

Theres a few ways to ‘relax’ the Same Origin Policy so you can actually interact with data from another domain.

1) CORS

Introduced relatively recently are a type of headers that tell your browser its ok with a requests from another domain. This is known as Cross Origin Resource Sharing or CORS. With these headers turned on, you can make POST & GETs just like you would with an endpoint on the same server as your script.

You will need access to the webserver configuration to make this happen, which is not an option for a site you have no control over. The guys over at enable-cors.org do a good job explaining how to enable this for the most common webservers.

Also, I should note, this is the only method that allows you to send a POST request to another domain.

In fact, here is our example

2) Proxy (with CORS)

This solution involves a middle man proxy that does have a CORS headers that passes along your request to a server that does not have CORS headers. Yes, this is a hack-y way to just make a cURL call to a webservice.

There is the hosted flavor (which is inherently unsafe, since they can see/log everything you send) or the self hosted variety.

3) JSONP

This is the most common way to make a GET request to another domain, and is probably the method with the least effort required.

The “P” in the JSONP actually stands for padding, which really means “Named Function”. You pass along a named javascript function that tells the server to wrap its response and when it responds your data is neatly wrapped with a helper function. This gets around the Same Origin Policy since <script> tags are ok’d for cross domain execution, which is how we can include JS libs from CDNs and other sources.

This method does require control over the request destination, or the site itself has to support a JSONP callback. This is just a javascript function returned from a ‘black box’, so there are some serious security concerns (but you’re not sending sensitive data via GET, right?). Also, we should note that this method have VERY limited support for reporting errors. Most people work around this by timing a response check and timeouts.

4) Cross Document Messaging

This method isn’t really possible with the $http object (the traditional way to make AJAX requests with AngularJS), but it’s still a viable option for some cross domain communication. I think it’s an interesting concept worth exploring and I think would be a cool way to explore promises and error states.

Conclusion

With some work and concessions, you can make cross domain requests. We’ll provide some working code examples soon.

D3 & MeteorJS

A talk John and I gave on D3 & MeteorJS at our last MeteorJS LA Meetup. We touched on some D3 basics, and discussed some challenges we faced integrating it with MeteorJS.

code available at: https://github.com/ArroyoLabs/meetups

demo: http://d3demo.meteor.com/