Last Saturday, I gave yet another talk on getting started with AngularJS and with good success. I found myself wondering though, along the way, why is it that we keep needing these “getting started” talks with Angular? What makes it so complicated? Why do we need endless “basic” tutorials?
I think the answer lies in the fact that AngularJS docs do not prepare you for Angular and good getting started tutorials don’t exist in the top 10 of google’s results. On top of that, finding one of your developer friends being an expert in Angular is impossible. In the grand scheme of things, it’s a small framework. Especially compared to the behemoth that jQuery is.
On top of that, we’re in the age of Udemy and similar services where you pay for a class as a way to thank an expert for sharing their knowledge. All of this makes Angular on-boarding difficult.
Markdown Editor is Markdown text editor online which helps user to test and view Markdown online. Angular Formatter. Use Angular 7, Node and Channels to build a live subscription countdown. The app features two interfaces: a signup dashboard, and a countdown view, showing how many places are left. Angular library that uses marked to parse markdown to html combined with Prism.js for synthax highlights.
- Update (March 22, 2016): Provided a Demo Link which is available on PlunkerUpdate (March 21, 2016): Updated a poorly formatted markdown. Angular 2 instead of Angular 2(https://angular.io).
- Oct 11, 2018 I've added angular DomSanitizer when MarkedOptions specify sanitize to true but not sanitizer function is provided. That way people have the choice to use the sanitizer they want or use angular one. This has been released in v6.3.0.
So I would like to rewrite my talk for you as a tutorial. You can view the presentation itself here and the code examples for the presentation on my github.
So before we get to “how to use Angular”, let’s discuss “why” and “what” Angular is.
About AngularJS
AngularJS is an MV*-style javascript framework. You may already be familiar with MVC architecture: model/view/controller. In Angular’s case (and many other frameworks’), the “controller” part is a little muddy. Unlike traditional back-end frameworks, the controller isn’t the middle man between the request and response but rather, it’s a scoped object that may contain functions, additional logic, and helps every part of the application interact together.
Now, despite AngularJS coming into the mainstream just about two years ago, its initial release was actually back in 2009. Its development really took off when one of the original creators started working at Google and over time, Google put its weight behind it, making it enterprise-ready over time.
What do I mean by that? Well, if you’ve ever spent any amount of time in the development world, you’ll know that long-term enterprise-y projects are 10% solution, 10% optimization, and 80% legibility under which I also classify architecture, maintenance and similar concepts. AngularJS does a good job separating different portions of an application into various files where a view, for instance, does not conflict with a controller or other libraries. Nothing is necessarily tied together except via dependency injection.
And since it’s backed by Google, we can bet that it will be around for a few years and won’t disappear into the nether (similar to what happened to KnockoutJS, unfortunately).
School Smart Paint Brushes, Set of 24. School Smart offers the products you need with the quality you expect at the prices you want. The assorted sizes of these paint brushes will help you create dynamic and intricate works of art. Paint brushes are an art class essential but. Smart paint brush. Smart Brush Painting offers small dry wall repairs, light carpentry, pressure washing, staining and maintenance touch ups Other Services Our Smart Brush team always goes the extra mile. ZenART Watercolor Paint Brushes – Smart 6 pc Black Tulip Short-Handle Watercolor Brush Set for Consistent Flow – Gouache, Watercolors, Fluid Acrylics, Inks - Synthetic Squirrel Hair, Vegan. Visit the ZenART Supplies Store. 4.7 out of 5 stars. USE WITH A VARIETY OF COATINGS: The SMART Roller can be used with latex paints, including paint-and-primer in one. Attach the fill tube to your paint can, press SMART Roller fill valve onto the tube, and pull back on the plunger to draw paint directly into the smart roller. Product description. Craftsmart 50 pcs Assorted All- Purpose Paint Brush Set for Acrylic, Oil, Watercolors. This exceptional set of artist' all purpose brushes is specially made for any painting artwork in oil, acrylic or watercolor mediums. Brush Care: Oil- Wash thoroughly in soap and water.
During my talk, I wanted to emphasize just how greatly AngularJS is enterprise-ready. It’s like Zend or Symfony for PHP or (the default) Java. Due to its architecture, new developers can jump in after learning the basics of Angular since most applications follow the semi-rigid pattern that Angular sets up.
Lastly, keep in mind that Angular is a FRONT-END framework that runs single-page apps. That means that what makes it special is that it can load and interact with data without reloading the page or having to rely on the server to figure out how to display data.
“Single Page Apps” the Old Way.
Or, “via jQuery”. Single Page Apps didn’t really exist until recently but before that happened, we TRIED and (somewhat) failed to build SAPs via jQuery. Our “apps” were more of “let me use jQuery to fetch a page and copy/paste that DOM into the current page”.
So let’s see how this was done and what problems arise along the way.
App 1
Easy, right? I think we’re all used to the typical jQuery syntax of “dom ready” and binding our listeners. That’s pretty much jQuery: an easy syntax for adding listeners and have those perform some kind of functionality. When jQuery first came out, it became the sugar on top of HTML. Meaning that you could submit a form without refreshing a page, add some neat animations, etc. But, you couldn’t do any super fancy stuff.
Everything is all fine and dandy in the world if you stick to this pattern.
App 2
Let’s look at another example that will illustrate the shortcomings of this approach.
If your first thought after looking at this code is “ew”, then you’re correct. It’s terrible code. It’s terrible jQuery, but unfortunately, it illustrates the reality of using a javascript library without templates to, well, do a workaround and try to template data nevertheless.
Now, given, jQuery is not meant to be used this way, there are plenty of people who have and continue to do so.
There is no way to template with jQuery, that means that we either have to use strings to concatenate strings of HTML and then have jQuery interpret it or do as I did above. While factories may help (passing information to a dedicated function that will build all this stuff for us), they end up doing the same stuff as before, just nicer.
Let’s get into the bigger problems.
As you can already tell, that code above is not only unmaintainable, it’s difficult to follow and understand. This creates a big problem. You know how I said most projects are 80% legibility? We’ve just failed that.
Here are the under-lying issues:
- listeners no longer work on new elements, the listeners have to attach on the parent-most element and wait for bubbling like so:
$('body').on('click', '.comment-like', function() {});
. This means, we’ll end up with a slew of listeners waiting at the top element where jQuery tries to figure out if the initial event dispatcher element matches what we need. - any state changes and updates have to be manually tracked. Since there is no two-way binding, we’ll need to implement our own listener/dispatcher system for data. To put this in perspective, if we have a counter for “comment likes”, we’ll have to manually fire off a “counting function” whenever a comment is liked, make sure that the comment is not double-counted, etc.
- There is no way to build a multi-page app. Separate pages would have to be either stashed somewhere or “display:none”d similar to how tabs work.
- Speed. Since we have to create work-arounds and extra code, we’ll most likely experience speed issues, this is something to consider. There are benchmarks you can check out on this matter, just make sure you dig deep enough to find fair and sensible comparisons.
- jQuery isn’t difficult to maintain by itself or for the purposes it was created. There are even certain design patterns for using jQuery; however, if you’re trying to build a single-page-app with jQuery, you’re better off hammering a nail with a t-shirt.
- Again, templating. Templating, templating, templating is the biggest issue here and AngularJS is pretty much the best framework out there for dealing with that.
Enter AngularJS
So what does AngularJS bring to the table? Lots:
Routing – server-side-like routing that allows us for the application to change the URL. Historyjs-like functionality included. This means that loading up a deep-linked page won’t cause any issues and wherever you go in the site, the URL will update.
Templating – a biggie. Not only does Angular have templating but it also supports handlebars-like templating for displaying data. This is contrary to, let’s say, KnockoutJS that used
data-bind
as an attribute to show data.Variable tracking / creates a model called “myText” bound to the $scope. The $scope is like a global variable, except scoped, depending on where you’re at. In our example, the $scope is part of
ng-app
, so anywhere within our file, we can call up the model and show it, or manipulate it.Ng-app is a way to tell angular “this is where our application starts” and it’s usually on the body tag or html tag.
Let’s move on, let’s do something with our data. There’s no sense in having an input box and having that information show on the other side of the page. Perhaps…perhaps, we can build a markdown editor!
Markdown Angular Tutorial
Let’s look at Step 2
What we’re doing here is creating a simple markdown editor. Enter text on the left, and output on the right in markdown. To do this, we’re going to change the data output to match our expectations, meaning that somewhere along the way, before the model gets shown on the page via {{ }}.
There are several ways to do it, so let’s checkout the code:
A few changes I made from the last example. First of all, I included showdown which is a markdown converter library. Second, I added some angular-specific code and lastly, I did away with {{ }}. Here’s what all of them mean.
The first line:
var app = angular.module('myapp', ['customFilters.markdown']);
We’re creating our application here. Angular no longer owns the entire page. We’re “scoping” things out a bit here. This allows us to run several separate angular applications on the same page. We won’t be doing that, but just like in casual sex, it’s good to wrap things up. You’ll notice that I moved the
ng-app
tag to the top and referenced our new application as ng-app='myapp'
, this tells angular that this particular page will be run by “myapp”.Angular does dependency injection, like I said earlier, the way it works here is why including it in that array up there. It’s customary, for large applications, to have a declaration list with all of the controllers, filters, and other parts of the application declared here. This makes those code segments (called “modules”) available to the application itself.
Markdown Angular Brackets
We passed in
customFilters.markdown
which is a custom module I made. I named it so to create a makeshift namespace pattern. I’d like to store all of our custom filters under the customFilters
name.First, there are different ways of declaring a “module” (a code segment that we can namespace and create dependencies list for). The way above is the best way in that it makes that module available for any Angular application that wants to inject it. The other way is to ignore namespacing (and thus make it un-injectable) and just append it to the app itself like so
app.filter('markdown')
. This is a bad idea and I ended up doing this for most of the steps.Anyways, so we created a new “filter”. A filter is a function that takes an input, modifies it, and returns it as output. This is what we want: take in markdown, convert it to HTML, and output. I’ll show you how to use those next. But before we get there, notice something in the filter. The filter itself returns a function that does all the work. Why? Because the filter actually CREATES the function that takes the input and does the work. In this case, we take advantage of that by creating only a single instance of the Showdown converter, and use it for all of our filter use.
The one thing you’ll see here is that we’re passing in a variable called “$sce”. This is a security feature of angular. Angular does not allow you to show straight HTML on a page from a variable. This neat variable lets you mark HTML as “safe” for angular to use and show on a page. Otherwise, angular would just show the HTML as plain text.
<div ng-bind-html='myText|markdown'>
<- lastly, we’re putting all this together and instead of using {{ }}, we’re using “ng-bind-html” which allows us to show html! ?In Step-3, we’re breaking things out a bit. Remember our filters? Well, we can “chain” them together. Meaning that we can do this:
myText | markdown | pretty
which would (in theory if we had a “pretty” filter) do this: pretty(markdown(myText))
. The input of myText
run through markdown
and then its output would go through pretty
. Here’s what we used that for:Here’s the relevant code:
Quickly, we created two filters. One that converts markdown into html, and the second filter that “trusts” that html. Which allows us to use
markdown
separately from trust
like so:The
myText|markdown|trust
will show our output and look all nice while myText|markdown
below will populate our <textarea>
with copy/pastable HTML.Data aggregation and angular templates
Markdown Angular Download
Already, you can create some neat stuff with the knowledge above, especially if you have javascript background. And that’s wonderful, but we’re just getting started going down this oddly shaped rabbit hole.
First, let me just say that one of the things that got me excited about Angular when I worked with KnockoutJS was the fact that an api feed could be consumed immediately without any post-processing. Any missing data would just yield an empty string. So for example, if we had a feed like this:
consume it and return it like this in a template:
If
meta
didn’t exist, it’d just end up empty. And notice, we didn’t have to do any pre-processing or create observables. In our controller (yep, we’re there already), we’ll just attach our feed to $scope and our application will monitor for value changes.Let’s look at Step 4
What happened here? I moved the filters out to a separate file (which is a good practice) and changed a few things out. First, let’s go over the bit above that says “controller”.
As I’ve said, Angular’s controllers aren’t true controllers. They’re more akin to mini-applications. In this case, our controller holds our comments. It uses
$scope
to make sure that this data is available in the view.When we bind this controller to our application, we use
ng-controller
. The semantics here should be self-explanatory.Further down, we get to see the scope information being used in the view like so:
ng-repeat
allows us to iterate through our comments just like a for loop. Yay! Templating! One of Angular’s little templating helpers. There are tons of others like ng-class
.Let’s move onto step 5 where we get to use REAL data.
A little emptier than the previous files, we moved over most of our logic to other files. Big applications would probably require further separation into folders called
controllers
, factories
, and such, with each subsequent module being in its own file.Before we get to the view, let’s check out our new
FeedController
.Sweet, so we declared our
FeedController
, and passed in a feedFactory
along with the scope? Yep, that’s right, we’ll look at that right after the controller. The feedFactory
is a piece of code that allows us to run a function that retrieves an API feed. As far as the sections of the code:$scope.feed
initializes an array that we can use in the view. Because of comment='newComment'></div>Another way to bind parts of the application is with the
&
symbol which basically means that we’re passing a function and allows us to call an outside function inside a directive. In this case, we’re referencing our addComment
function in the controller and we’re calling it inside the directive as onAddComment
. Lastly, the @
symbol passes the information through as a string.This may sound a bit confusing and that’s because directives are their own rabbit hole with various settings and possibilities of use. I recommend reading further into it once you grasp the basics of everything else.
So let me explain what else we’re doing:
replace: true,
This means that the original element we used (
<div comment-form></div>
Bartender curse. ) will disappear and be replaced by the template inside the directive. If you leave out the replace
part, the template will be wrapped with the <div></div>
we declared.Last but not least, our
link
function:Things should start looking familiar. We’re passing in a scope. There are some other dependencies that made their way here but let’s not concern ourselves with those at this moment.
Since you’ve already seen the template (above), this function should look self-explanatory. We have a comment on the scope which is bound to the
textarea
for that new comment. And we have a function that fires off when our form
is submitted. The function, you’ll notice, is named exactly the same as in our scope declaration earlier. In the directive declaration in our template (the <div></div>
), we had an attribute called on-add-comment
. This is the same thing.We passed in
scope.comment
which is then passed to our controller’s own function addComment
. Since we already prefilled the $index
part there, we don’t have to pass it in again. We also don’t have a way to pass it in unless we augmented our scope
declaration and made a new variable.Where to now?
Now that we’re done with the beginner’s guide, it’s time to move on, move forward. I’d say that your best shot learning AngularJS is to start making apps. Make a twitter feed with twitter’s API, or a simple tool for yourself, whether it’s a to-do list, or a simple tool for finding movies by actors.
Or, build a blog. It’s all up to you ?
Additional Resources
Want to take the next step? Here are some good resources on getting there:
Free:
- Checkout Egghead – “Bite-sized video training with AngularJS”
Paid:
- Angular a bit over your head? Try TeamTreehouse for Javascript basics