Quickstart

Dart

Our QuickStart goal is to build and run a super-simple Angular 2 application in Dart, and establish a development environment for the remaining documentation samples that also can be the foundation for real world applications.

Don't want Dart?

Although we're getting started in Dart, you can also write Angular 2 apps in TypeScript and JavaScript. Just select either of those languages from the combo-box in the banner.

Try it!

Try the which loads the sample app in plunker and displays the simple message:

Output of QuickStart app

Build this app!

Prerequisite: the Dart SDK

Install the Dart SDK, if not already on your machine, and any tools you like to use with Dart. The Dart SDK includes tools such as pub, the Dart package manager. If you don't have a favorite Dart editor already, try WebStorm, which comes with a Dart plugin. You can also download Dart plugins for other IDEs and editors.

Download the source

Instead of following each step of these instructions, we can download the QuickStart source from GitHub and follow its brief instructions.

Explanations describe the concepts and reasons behind the instructions. Explanations have a thin border on the left like this block of text.

Click Hide Explanations to show only the instructions. Click View Explanations to see everything again.

We'll see many code blocks as we build the QuickStart app. They're all easy to copy and paste:

Click the glyph on the right to copy code snippets to the clipboard ==>

Step 1: Create and configure the project

In this step we:

(a) Create the project folder

mkdir angular2_quickstart cd angular2_quickstart

(b) Add pubspec.yaml

In the project folder just created, create a file named pubspec.yaml with the code below. This pubspec must specify the angular2 and browser packages as dependencies, as well as the angular2 transformer. It can also specify other packages and transformers for the app to use, such as dart_to_js_script_rewriter.

pubspec.yaml

name: angular2_quickstart description: QuickStart version: 0.0.1 environment: sdk: '>=1.19.0 <2.0.0' dependencies: angular2: ^2.0.0 dev_dependencies: browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: - angular2: platform_directives: - 'package:angular2/common.dart#COMMON_DIRECTIVES' platform_pipes: - 'package:angular2/common.dart#COMMON_PIPES' entry_points: web/main.dart - dart_to_js_script_rewriter

(c) Get packages

From the project folder, run pub get to install the angular2 and browser packages (along with the packages they depend on).

> pub get Resolving dependencies...

We're all set. Let's write some code.

Step 2: Our first Angular component

Let's create a folder to hold our application and add a super-simple Angular component.

Create a lib subfolder off the project root directory:

mkdir lib

Create the component file lib/app_component.dart (in this newly created directory) with the following content:

lib/app_component.dart

import 'package:angular2/core.dart'; @Component( selector: 'my-app', template: '<h1>My First Angular App</h1>') class AppComponent {}

AppComponent is the root of the application

Every Angular app has at least one root component, conventionally named AppComponent, that hosts the client user experience. Components are the basic building blocks of Angular applications. A component controls a portion of the screen — a view — through its associated template.

This QuickStart has only one, extremely simple component. But it has the essential structure of every component we'll ever write:

Import

Angular apps are modular. They consist of many files each dedicated to a purpose. Angular itself is modular. It is a collection of library modules each made up of several, related features that we'll use to build our application.

When we need something from a module or library, we import it. Here we import the Angular 2 core so that our component code can have access to the @Component annotation.

lib/app_component.dart (import)

import 'package:angular2/core.dart';

@Component annotation

@Component is an annotation that allows us to associate metadata with the component class. The metadata tells Angular how to create and use this component.

lib/app_component.dart (metadata)

@Component( selector: 'my-app', template: '<h1>My First Angular App</h1>')

The call to the @Component constructor has two named parameters, selector and template.

The selector specifies a simple CSS selector for an HTML element that represents the component.

The element for this component is named my-app. Angular creates and displays an instance of our AppComponent wherever it encounters a my-app element in the host HTML.

The template specifies the component's companion template, written in an enhanced form of HTML that tells Angular how to render this component's view.

Our template is a single line of HTML announcing "My First Angular App".

A more advanced template could contain data bindings to component properties and might identify other application components which have their own templates. These templates might identify yet other components. In this way an Angular application becomes a tree of components.

Component class

At the bottom of the file is an empty, do-nothing class named AppComponent.

lib/app_component.dart (class)

class AppComponent {}

When we're ready to build a substantive application, we can expand this class with properties and application logic. Our AppComponent class is empty because we don't need it to do anything in this QuickStart.

Step 3: Add main.dart

Now we need something to tell Angular to load the root component. Create:

web/main.dart

import 'package:angular2/platform/browser.dart'; import 'package:angular2_quickstart/app_component.dart'; void main() { bootstrap(AppComponent); }

We import the two things we need to launch the application:

  1. Angular's browser bootstrap function
  2. The application root component, AppComponent.

Then we call bootstrap with AppComponent.

Bootstrapping is platform-specific

Notice that we import the bootstrap function from angular2/platform/browser.dart, not angular2/core.dart. Bootstrapping isn't core because there isn't a single way to bootstrap the app. True, most applications that run in a browser call the bootstrap function from this library.

But it is possible to load a component in a different environment. We might load it on a mobile device with Apache Cordova or NativeScript. We might wish to render the first page of our application on the server to improve launch performance or facilitate SEO. These targets require a different kind of bootstrap function that we'd import from a different library.

Why create separate main.ts, app module and app component files?

Then main.ts, app module and the app component files are tiny. This is just a QuickStart. We could have merged these files into one and spared ourselves some complexity.

We'd rather demonstrate the proper way to structure an Angular application. App bootstrapping is a separate concern from creating a module or presenting a view. Mixing concerns creates difficulties down the road. We might launch the AppComponent in multiple environments with different bootstrappers. Testing the component is much easier if it doesn't also try to run the entire application. Let's make the small extra effort to do it the right way.

Step 4: Add index.html

In the web folder create an index.html file and paste the following lines into it:

web/index.html

<!DOCTYPE html> <html> <head> <title>Getting Started</title> <link rel="stylesheet" href="styles.css"> <script defer src="main.dart" type="application/dart"></script> <script defer src="packages/browser/dart.js"></script> </head> <body> <my-app>Loading...</my-app> </body> </html>

The index.html file defines the web page that hosts the application.

When Angular calls the bootstrap function in main.ts, it reads the AppComponent metadata, sees that AppComponent is the bootstrap component, finds the my-app selector, locates an element tag named my-app, and renders our application's view between those tags.

Add some style

Styles aren't essential but they're nice, and index.html assumes we have a stylesheet called styles.css.

Create a styles.css file in the web folder and start styling, perhaps with the minimal styles shown below.

web/styles.css (excerpt)

/* Master Styles */ h1 { color: #369; font-family: Arial, Helvetica, sans-serif; font-size: 250%; } h2, h3 { color: #444; font-family: Arial, Helvetica, sans-serif; font-weight: lighter; } body { margin: 2em; }

For the full set of master styles used by the documentation samples, see styles.css.

Step 5: Build and run the app!

We have a few options for running our app. One is to launch a local HTTP server and then view the app in Dartium. We can use any web server, such as WebStorm's server or Python's SimpleHTTPServer.

Another option is to build and serve the app using pub serve, and then run it by visiting http://localhost:8080 in any modern browser. Pub serve generates JavaScript on the fly, which can take a while when first visiting the page. Pub serve also runs in watch mode, and will recompile and subsequently serve any changed assets.

Once the app is running, the browser window should show the following:

Output of QuickStart app

Great job!

If you don't see My First Angular App, make sure you've entered all the code correctly, in the proper folders, and run pub get.

Building the app (generating JavaScript)

Before deploying the app, we need to generate JavaScript files. The pub build command makes that easy.

> pub build Loading source assets...

The generated JavaScript appears, along with supporting files, under a directory named build.

Using the Angular transformer

When generating JavaScript for an Angular app, be sure to use the Angular transformer. It analyzes the Dart code, converting reflection-using code to static code that Dart's build tools can compile to faster, smaller JavaScript. The highlighted lines in pubspec.yaml configure the Angular transformer:

pubspec.yaml

name: angular2_quickstart description: QuickStart version: 0.0.1 environment: sdk: '>=1.19.0 <2.0.0' dependencies: angular2: ^2.0.0 dev_dependencies: browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: - angular2: platform_directives: - 'package:angular2/common.dart#COMMON_DIRECTIVES' platform_pipes: - 'package:angular2/common.dart#COMMON_PIPES' entry_points: web/main.dart - dart_to_js_script_rewriter

The entry_points item identifies the Dart file in our app that has a main() function. For more information, see the Angular transformer wiki page.

Performance, the transformer, and Angular 2 libraries

When an app imports bootstrap.dart, it also gets dart:mirrors, a reflection library that causes performance problems when compiled to JavaScript. Don't worry, the Angular transformer converts the app's entry points (entry_points in pubspec.yaml) so that they don't use mirrors.

Using dart_to_js_script_rewriter

To improve the app's performance, convert the HTML file to directly include the generated JavaScript; one way to do that is with dart_to_js_script_rewriter. To use the rewriter, specify dart_to_js_script_rewriter in both the dependencies and transformers sections of the pubspec.

pubspec.yaml

name: angular2_quickstart description: QuickStart version: 0.0.1 environment: sdk: '>=1.19.0 <2.0.0' dependencies: angular2: ^2.0.0 dev_dependencies: browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: - angular2: platform_directives: - 'package:angular2/common.dart#COMMON_DIRECTIVES' platform_pipes: - 'package:angular2/common.dart#COMMON_PIPES' entry_points: web/main.dart - dart_to_js_script_rewriter

The dart_to_js_script_rewriter transformer must be after the angular2 transformer in pubspec.yaml.

For more information, see the docs for dart_to_js_script_rewriter.

Make some changes

Try changing the message to "My SECOND Angular app".

To see the new version, just reload the page.

Be sure to terminate the pub serve process once you stop working on this app.

Wrap up

Our final project folder structure looks like this:

angular2_quickstart
lib
app_component.dart
pubspec.yaml
web
index.html
main.dart
styles.css

This figure doesn't show generated files and directories. For example, a pubspec.lock file specifies versions and other identifying information for the packages that our app depends on. The pub build command creates a build directory containing the JavaScript version of our app. Pub, IDEs, and other tools often create other directories and dotfiles.

Here are the file contents:

import 'package:angular2/core.dart'; @Component( selector: 'my-app', template: '<h1>My First Angular App</h1>') class AppComponent {} import 'package:angular2/platform/browser.dart'; import 'package:angular2_quickstart/app_component.dart'; void main() { bootstrap(AppComponent); } <!DOCTYPE html> <html> <head> <title>Getting Started</title> <link rel="stylesheet" href="styles.css"> <script defer src="main.dart" type="application/dart"></script> <script defer src="packages/browser/dart.js"></script> </head> <body> <my-app>Loading...</my-app> </body> </html> name: angular2_quickstart description: QuickStart version: 0.0.1 environment: sdk: '>=1.19.0 <2.0.0' dependencies: angular2: ^2.0.0 dev_dependencies: browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: - angular2: platform_directives: - 'package:angular2/common.dart#COMMON_DIRECTIVES' platform_pipes: - 'package:angular2/common.dart#COMMON_PIPES' entry_points: web/main.dart - dart_to_js_script_rewriter /* Master Styles */ h1 { color: #369; font-family: Arial, Helvetica, sans-serif; font-size: 250%; } h2, h3 { color: #444; font-family: Arial, Helvetica, sans-serif; font-weight: lighter; } body { margin: 2em; }

What next?

Our first application doesn't do much. It's basically "Hello, World" for Angular 2.

We kept it simple in our first pass: we wrote a little Angular component, created a simple index.html, and launched with a static file server. That's about all we'd expect to do for a "Hello, World" app.

We have greater ambitions!

We're about to take the next step and build a small application that demonstrates the great things we can build with Angular 2.

Join us on the Tour of Heroes Tutorial!