Wednesday, April 26, 2017

Angular 4.1.0 Now Available

Angular version 4.1.0 - is now available. This is a minor release following our announced adoption of Semantic Versioning, meaning that it contains no breaking changes and that it is a drop-in replacement for 4.x.x.

What's new?
  • Version 4.1 adds full support for TypeScript 2.2 and 2.3. Developers previously reported good experiences with TypeScript 2.2 and 2.3, but Angular is now built with TypeScript 2.3. This does not affect our support for TypeScript 2.1 which shipped with 4.0.
  • Angular is now compliant with TypeScript’s StrictNullChecks. This means that you can enable StrictNullChecks in your project, if desired.

For the complete list of features and bugfixes please see the changelog.

Monday, April 10, 2017

Official languages at Google

Following my keynote at ng-conf 2017 that seemed to indicate that Typescript is now an official language at Google, there were many questions about the status of Dart at Google.

We would like to clarify that both Dart and Typescript are in the same category. They both are  allowed to be used for client side development. They are, however, not in the same category as more established languages like Javascript/Closure and Java — those have both more lines of code and more tooling.

Dart has been used for unrestricted client development at Google now for 4+ years. Dart and AngularDart are used by large products such as AdWords, AdSense and Shopping, and by critical internal tools such as Google CRM. In addition, the Flutter cross-platform mobile app framework uses Dart and is used by multiple teams at Google including Google CRM and Shopping Express. The Google codebase contains many millions of lines of Dart code.

Typescript has become allowed for unrestricted client development as of March 2017. TypeScript and Angular on TypeScript are used in Google Analytics, Firebase, and Google Cloud Platform and critical internal tools such as bug tracking, employee reviews, and product approval and launch tools.

We are happy to say that teams at Google have a choice between many client side languages and can choose the best one for their needs.

Thursday, March 23, 2017

Angular 4.0.0 Now Available

Angular version 4.0.0 - invisible-makeover - is now available. This is a major release following our announced adoption of Semantic Versioning, and is backwards compatible with 2.x.x for most applications.

We are very excited to share this release with the community, as it includes some major improvements and functionality that we have been working on for the past 3 months. We’ve worked hard to make sure that it’s easy for developers to update to this release.

What’s New

Smaller & Faster

In this release we deliver on our promise to make Angular applications smaller and faster. By no means are we done yet, and you'll see us being focused on making further improvements in the coming months.

View Engine

We’ve made changes under to hood to what AOT generated code looks like. These changes reduce the size of the generated code for your components by around 60%  in most cases. The more complex your templates are, the higher the savings.
During our release candidate period, we heard from many developers that migrating to 4 reduced their production bundles by hundreds of kilobytes.
Read the Design Doc to learn more about what we did with the View Engine.

Animation Package

We have pulled animations out of @angular/core and into their own package. This means that if you don’t use animations, this extra code will not end up in your production bundles.
This change also allows you to more easily find documentation and to take better advantage of autocompletion. You can add animations yourself to your main NgModule by importing BrowserAnimationsModule from @angular/platform-browser/animations.

New Features

Improved *ngIf and *ngFor

Our template binding syntax now supports a couple helpful changes. You can now use an if/else style syntax, and assign local variables such as when unrolling an observable.
<div *ngIf="userList | async as users; else loading">
 <user-profile *ngFor="let user of users; count as count; index as i" [user]="user"> User {{i}} of {{count}}
 </user-profile>
</div>
<ng-template #loading>Loading...</ng-template>

Angular Universal

Universal, the project that allows developers to run Angular on a server, is now up to date with Angular again, and this is the first release since Universal, originally a community-driven project, was adopted by the Angular team. This release now includes the results of the internal and external work from the Universal team over the last few months. The majority of the Universal code is now located in @angular/platform-server.

To learn more about taking advantage of Angular Universal, take a look at the new renderModuleFactory method in @angular/platform-server, or Rob Wormald’s Demo Repository. More documentation and code samples are forthcoming.

TypeScript 2.1 and 2.2 compatibility

We’ve updated Angular to a more recent version of TypeScript. This will improve the speed of ngc and you will get better type checking throughout your application.

Source Maps for Templates

Now when there is an error caused by something in one of your templates, we generate source maps that give a meaningful context in terms of the original template.

Packaging Changes

Flat ES Modules (Flat ESM / FESM)

We now ship flattened versions of our modules ("rolled up" version of our code in the EcmaScript Module format, see example file). This format should help tree-shaking, help reduce the size of your generated bundles, and speed up build, transpilation, and loading in the browser in certain scenarios.

Read more about the importance of Flat ES Modules in "The cost of small modules".

Experimental ES2015 Builds

We now also ship our packages in the ES2015 Flat ESM format. This option is experimental and opt-in. Developers have reported up to 7% bundle size savings when combining these packages with Rollup. To try out these new packages, configure your build toolchain to resolve "es2015" property in package.json over the regular "module" property.

Experimental Closure Compatibility

All of our code now has Closure annotations, making it possible to take advantage of advanced Closure optimizations, resulting in smaller bundle sizes and better tree shaking.

Updating to 4.0.0

Updating to 4 is as easy as updating your Angular dependencies to the latest version, and double checking if you want animations. This will work for most use cases.

On Linux/Mac:
npm install @angular/{common,compiler,compiler-cli,core,forms,http,platform-browser,platform-browser-dynamic,platform-server,router,animations}@latest typescript@latest --save
On Windows:
npm install @angular/common@latest @angular/compiler@latest @angular/compiler-cli@latest @angular/core@latest @angular/forms@latest @angular/http@latest @angular/platform-browser@latest @angular/platform-browser-dynamic@latest @angular/platform-server@latest @angular/router@latest @angular/animations@latest typescript@latest --save
Then run whatever ng serve or npm start command you normally use, and everything should work.
If you rely on Animations, import the new BrowserAnimationsModule from @angular/platform-browser/animations in your root NgModule. Without this, your code will compile and run, but animations will trigger an error. Imports from @angular/core were deprecated, use imports from the new package import { trigger, state, style, transition, animate } from '@angular/animations';.
We are beginning work on an interactive Angular Update Guide if you would like to see more information about making any needed changes to your application.

Known Issues

One of the goals for version 4 was to make Angular compatible with TypeScript's strictNullChecks setting, allowing for a more restrictive subset of types to be mandated. We discovered during the RC period that there is more work to be done for this to function properly in all use cases, so we intentionally made 4.0 incompatible with the strictNullChecks setting in order to  avoid breaking apps that would otherwise eagerly adopt this TypeScript mode when the proper support lands in 4.1 (tracking issue is #15432).

What's next?

We are in the process of setting the roadmap for the next 6 months, following the same cadence as our published release schedule for 2.x. You'll see patch updates to 4.0.0 and we are already getting started on 4.1. We are going to continue making Angular smaller and faster, and we're going to evolve capabilities such as @angular/http, @angular/service-worker, and @angular/language-service out of experimental.

You should also stay tuned for updates to our documentation, a stable release of the CLI, and guidance for library authors on packaging.

Friday, January 27, 2017

Branding Guidelines for Angular and AngularJS

Angular
In September of last year we made several big announcements. We released version 2.0.0 of Angular and that we were adopting Semantic Versioning, meaning that developers will see version number increases in a planned and careful manner. As a result of these announcements, you’ve seen us using the term Angular to refer to all versions of the framework after 2.0.0.


We’ve had a great response from Developers about this. Bloggers and authors and discussions boards can in most contexts drop the version number from discussions of Angular, because the tutorials, tips, tricks, and content that works in version 2 will work in version 4, and likely beyond. This allows those discussing Angular to talk about the framework without becoming prematurely dated each time there’s a version bump.


Here’s an example tutorial you could write:


Correct
Angular Router Guide - Learn about how to use the Router in Angular as the basis for page animations, analytics tracking, and how to fetch parameters and data reactively from the router.
Incorrect
Angular 2 Router Guide - Learn about how to use the Angular 2 Router as the basis for page animations, analytics tracking, and how to fetch parameters and data reactively from the router.

Reasoning
By not using “Angular 2” in the title, the content still feels applicable and useful after version 4, 5, 6, 7, etc have been released, as the syntax is unlikely to change.


AngularJS
Our announcements around “It’s just Angular" were the first step in bringing consistency into the naming of the platform and the ecosystem. Our recommendation last month was to use Angular 1 for all 1.x versions of the framework and Angular for all the subsequent versions (unless a version was required for clarification in a given context). We heard from the community that because AngularJS has been used for for so long, it would be too hard and confusing to "rewrite history" across the web and the physical world.


We agree with this and we have accepted the suggestions many of you have brought up to return to our roots with the name AngularJS for any 1.x release, and Angular for any 2+ release. Our goal is to bring as much consistency as possible especially going forward, while reducing the maintenance burden caused by past branding inconsistencies.


These new guidelines match what already exists in a number of ways. If you are looking for a book on version 1.x, you’ll probably find it with the name AngularJS. And as more content is written consistently using these guidelines, it should become easier to search for what you are looking for.




What about Angular Material?
Angular Material is a project led by Google to build a great reusable component library for Angular Developers. The Material project takes Google’s design principles, and boils them down into components you can add your projects. We are continuing to invest in Material as a great choice for developers working with either Angular or AngularJS. To match the name guidelines, we’re clarifying the naming of the projects to “Angular Material” and “AngularJS Material”.


Brand Guidelines
For the full guidelines, check out our Press Kit.

We've been propagating these standards across all of our projects over the last week or so, but there's more work to be done. You can help by using these names to build consistency across the ecosystem! Here are some handy regular expressions if you'd like to help us fix the branding in your projects!
s/angular (1\.\d)/AngularJS $1/ig
s/angular 1\.x/AngularJS/ig
s/angular 1/AngularJS/ig
s/angular1/AngularJS/ig
s/angular 2\.0/Angular/ig
s/angular 2/Angular/ig
s/angular 2\.x/Angular/ig
s/angular2/Angular/ig

Friday, January 13, 2017

Understanding AOT and Dynamic Components

This is a guest post from Sean Landsman at ag-Grid. Sean is the lead engineer on ag-Grid's Angular integration. -- Stephen Fluin


Motivation

ag-Grid is an enterprise datagrid that works with Angular. As ag-Grid works with many frameworks, the internals of the grid had to allow for Angular rendering inside the grid despite ag-Grid not being written in Angular itself. This was done using Angular Dynamic Components and we managed to do it while still supporting AOT. This blog details what we learnt along the way.

The Setup

To explain we present a simple sample application that isolates what we are trying to do. In our example below we are going to develop two main Modules - one will be a Library (in our case this was ag-Grid) that will display an array of dynamically created Components (similar to how ag-Grid displays Angular components inside the grid's cells), and the other will be our actual Application.
The end result will be look like this:




You can find all the code for this example over at GitHub, and the live example over at GitHub.io
One further note - when we return to "user" below, we are referring to a user (or client) of the Library we're writing.

The Library

Our Library is going to be a simple one - all it does is display an array of dynamically created Angular Components. The main component looks like this:

@Component({
    selector: 'grid-component',
    template: `
        <div class="row" *ngFor="let cellComponentType of cellComponentTypes">
            <div class="col-lg-12">
                <grid-cell [componentType]="cellComponentType"></grid-cell>
            </div>
        </div>
    `
})
export class Grid {
    @Input() componentTypes: any;

    cellComponentTypes: any[] = [];

    addDynamicCellComponent(selectedComponentType:any) {
        this.cellComponentTypes.push(selectedComponentType);
    }
}

As you can see it's a pretty simple component - all it does is display the current cellComponentTypes. These are the user supplied components, and they can be any Angular Component.

The interesting part of the Library is in the Cell Component:

@Component({
    selector: 'grid-cell',
    template: ''
})
export class Cell implements OnInit {
    @Input() componentType: any;

    constructor(private viewContainerRef: ViewContainerRef,
                private cfr: ComponentFactoryResolver) {
    }

    ngOnInit() {
        let compFactory = this.cfr.resolveComponentFactory(this.componentType);
        this.viewContainerRef.createComponent(compFactory);
    }
}

You'll notice that we don't have a template here - that's deliberate as the Cell doesn't have any
    content of its own - all it does is serve up the user supplied Component. The important part of this Component are
    these two lines:

let compFactory = this.cfr.resolveComponentFactory(this.componentType);

This line asks the ComponentFactoryResolver to find the ComponentFactory for the provided
    Component. We'll use this factory next to create the actual component:

this.viewContainerRef.createComponent(compFactory);

And that's all there is to it from the Library Component side of things - we find the factory for the Component, and
    then create a new instance of the Component. Easy!

For this to work we need to tell Angular's AOT Compiler to create factories for the user provided Components, or ComponentFactoryResolver won't find them. We can make use of NgModule.entryComponents for this - this will ensure that the AOT compiler creates the necessary factories, but for you purposes there is an easier way, especially from a users perspective:

@NgModule({
    imports: [
        BrowserModule,
        FormsModule
    ],
    declarations: [
        Grid,
        Cell
    ],
    exports: [
        Grid
    ]
})
export class GridModule {
    static withComponents(components: any[]) {
        return {
            ngModule: GridModule,
            providers: [
                {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: components, multi: true}
            ]
        }
    }
}

By making use of ANALYZE_FOR_ENTRY_COMPONENTS here, we are able to add multiple components to the NgModule.entryComponents
    entry dynamically, in a user friendly way.

The Application

From the application side of things, the first thing we need to do is create the components we want to use in the Library - these can be any valid Angular Component. In our case we have three similar Components:

@Component({
    selector: 'dynamic-component',
    template: '<div class="img-rounded" style="background-color: lightskyblue;margin: 5px"> Blue Dynamic Component! </div>',
})
export class BlueDynamicComponent {
}

All these components do is display a little styled text.
To register these in both our Application, and in the Library, we need to switch to the Application Module:

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        GridModule.withComponents([
            BlueDynamicComponent,
            GreenDynamicComponent,
            RedDynamicComponent
        ])
    ],
    declarations: [
        AppComponent,
        BlueDynamicComponent,
        GreenDynamicComponent,
        RedDynamicComponent
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}


We declare our Components in the usual way, but we additionally need to register them with the Library (remember,
    this is the part where they'll be added to the
    Library's NgModule.entryComponent entry). We do this in this part of the module:

GridModule.withComponents([
    BlueDynamicComponent,
    GreenDynamicComponent,
    RedDynamicComponent
])


Finally, we can take a look at the main Application Component:

@Component({
    selector: 'my-app',
    template: `
        <div class="container-fluid">
            <div class="page-header">
                <h1>Creating AOT Friendly Dynamic Components with Angular
</div>
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">Application Code</div>
                        <div class="panel-body">
                            <div class="input-group">
                                <span class="input-group-btn">
                                    <button type="button" class="btn btn-primary" (click)="grid.addDynamicCellComponent(selectedComponentType)">Add Dynamic Grid component
    </span>

                                <select class="form-control" [(ngModel)]="selectedComponentType">
                                    <option *ngFor="let cellComponentType of componentTypes" [ngValue]="cellComponentType">{{cellComponentType.name}}
    </select>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">Library Code</div>
                        <div class="panel-body">
                            <grid-component #grid></grid-component>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    `
})
export class AppComponent implements OnInit {
    @Input() componentTypes: any[] = [BlueDynamicComponent, GreenDynamicComponent, RedDynamicComponent];
    @Input() selectedComponentType: any;

    ngOnInit(): void {
        // default to the first available option
        this.selectedComponentType = this.componentTypes ? this.componentTypes[0] : null;
    }
}

It may look like theres a lot going on here, but the bulk of the template is to make it look pretty. The key parts of this Component are:

<button type="button" class="btn btn-primary" (click)="grid.addDynamicCellComponent(selectedComponentType)">Add Dynamic Grid component

This will ask the Library to add a create a new instance of the supplied Component, and in turn render it.

<grid-component #grid></grid-component>


And this line is our Library Component.

That's it - easy to write and use (from both an Application and Library perspective), and AOT (and JIT!) friendly.

Benefits of using AOT

The speed and size of the resulting application when using AOT can be significant. In our ag-grid-ng2-example project, we estimate the size of the resulting application went from 3.9Mb down to 2.4Mb - a reduction of just under 40%, without optimising for size or being particularly aggressive with rollup.

Speed-wise, the loading time when using AOT is significantly more responsive on startup - this makes sense given that Angular doesn't have to compile all the code once again. Take a look at the examples project and try both the JIT and AOT versions out for yourself!

There's so much more you can do if you decide to combine Angular Components with ag-Grid - powerful functionality, fast grid and easy configuration. What are you waiting for?!

Thursday, December 22, 2016

Angular Material Beta Release, New Flex-Layout library

We're sneaking in a little holiday gift at the end of the year: two new beta releases for developers to try out with the latest version of Angular.

material components with a custom theme and RTL text

In March, we gave you a first preview of the new Angular Material components. Today's beta release of @angular/material includes 22 UI components written for the latest Angular: button, button‑toggle, card‑list, chips, checkbox, dialog, grid‑list, icon, input, menu, progress‑bar, progress‑spinnerradio‑buttonselectsidenavslide‑toggleslidersnackbartextareatoolbar, and tooltip. It also provides support for accessibility, custom themes, and RTL text.  For documentation and examples, see material.angular.io.

Also out in beta today, the new @angular/flex-layout package is a general-purpose flex-based layout library for use in any Angular application later than version 2.4. It provides a responsive engine and API to easily define how UI layouts should update as viewport sizes change with orientation across different display devices. The HTML API makes it trivial to quickly arrange (and auto-resize) web page component layouts. In Angular 1.x, layout tools were included as part of Angular Material. With flex-layout, we have made layout a standalone library, decoupled from the UI components. Learn more about the flex-layout beta here.

Whether you're building a new app, or upgrading from a legacy Angular 1.x app that needs Layout and Angular Material APIs, these components will help you to quickly build a beautiful and performant UI consistent with Google's Material Design spec.

What does beta mean?

We've built all of the core UI components that most applications will need. Start using these libraries, and give us feedback on GitHub.

We don’t plan to make any large API changes before exiting beta, however we’ll make changes based on feedback we receive during the beta process.

What's still in the works?

For Angular Material, developers can expect other advanced components (e.g. data-table, date-picker), and typography support. Both libraries will see ongoing bug fixes and feature improvements.
For users on Angular Material 1.x, a new release is expected in early 2017 with bug fixes and security improvements.

Tuesday, December 20, 2016

Angular 2.4.0 Now Available

Angular version 2.4.0 - stability-interjection - is now available. This is a minor release following our announced adoption of Semantic Versioning, meaning that it contains no breaking changes and that it is a drop-in replacement for 2.x.x.

What's new?
    • This release updates our dependencies to the recently announced RxJS 5 stable

For the complete list of features and bugfixes please see the changelog.