Wednesday, March 30, 2016

Code Reuse in Angular 2 Native Mobile Apps with NativeScript

Please welcome Nathan Walker as a guest-author on the Angular blog.  Read on to find out more about building cross-platform apps with Angular 2 and NativeScript.

The zen of multiple platforms.  Chrome, Android and iPhone all running the same code.
You may have felt the tremors reverberating from the bowels of Twitter or elsewhere about writing pure Native mobile apps in JavaScript. This is not hybrid, Cordova or webviews. These are truly native, 60fps mobile applications written with JavaScript. But that leaves one wondering: If there is no webview, how can I re-use my application code between the web and my mobile app?

The answer is you need a JavaScript framework smart enough to do it, and a mobile runtime powerful enough to support it.

Angular 2 is that framework, and NativeScript is that runtime.

In this article, I'm going to show you how to create a single application with Angular 2 that can be rendered on the web, or rendered in a native mobile application with NativeScript. Here's what you can expect to learn:

  • How to build a Native mobile app from your existing web app codebase.
  • How NativeScript can fit perfectly in the mix with your Angular 2 web app.
  • How to utilize all of our existing web codebase with minimal to zero disruption. 
  • How to configure Angular's Component to use the right view template on the right platform.
  • About a powerful feature in Angular 2: Decorators.

The strategy presented is used in the angular2-seed-advanced project (exemplified in image above). It exists for you to learn from, use directly for one of your projects as well as gather community feedback on potential integration improvements. In addition to NativeScript, it also supports ngrx/store for RxJS powered state management (Redux inspired), ng2-translate for i18n, lodash for reduction of boilerplate and more coming soon.

Disclaimer: As always, there are multiple ways to achieve the same goal. Alternative strategies are welcome  and/or improvements to the one presented.

What is NativeScript? Brief Background

NativeScript, {N} for short, is an open source JavaScript framework that lets you build native mobile apps from a single code base. NativeScript works by leveraging JavaScript virtual machines—e.g. JavaScriptCore and V8—to create a bridge between the JavaScript code you write and the native APIs used to drive the native application.

One notable and very exciting benefit is you will gain the ability to create truly Native components that are highly performant and feel natural on both Android or iOS.

Angular 2's powerful and extensible architecture makes this possible and the ability to integrate the two technologies is achieved via nativescript-angular, a custom renderer for Angular 2 which makes it possible for Angular 2 templates to render native iOS and Android controls. More background and an excellent overview of this integration is presented here by TJ Vantoll.

If you're just learning about Angular 2 and curious about the new Rendering Architecture, you can learn more about that here.

Angular 2 + NativeScript FAQ

Let me help by highlighting a few common questions/concerns you might have.

Q: Does NativeScript render native mobile apps from HTML?

A: No. NativeScript uses XML, but both HTML and XML are just markup languages. Perfect for constructing UI. It's all just angle brackets.

Q: Do I need to create a separate NativeScript XML template for each HTML template?

A: Yes.

Q: Isn't that pretty disruptive though?

A: Actually No. With Angular 2's Component Decorator, this becomes pretty...well...non-disruptive.

Decorators add the ability to augment a class and its members as the class is defined, through a declarative syntax. To help illustrate, let's look at a Decorator you get for free by the Angular 2 framework:

import {Component} from 'angular2/core';

@Component({
  selector: 'sample'
  templateUrl: './components/sample.component.html'
})
export class SampleComponent {}

@Component is a Decorator that declaratively augments the SampleComponent class by defining specific metadata about the class; in this case: a selector for it's use in the browser's DOM and a templateUrl to define a view. Because Angular 2 was built with extensibility in mind, you are not constrained by only the Decorators the framework provides, but rather you can extend these Decorators to create your own.

In keeping with our goal to be as non-disruptive as possible with our NativeScript integration into our existing web app codebase, we are going to create our own custom Decorator, leveraging the power and elegance of Angular 2's Component Decorator by extending to augment with new capabilities allowing our NativeScript integration to be seamless. This will allow us to share code between our web app that runs in the browser, and your mobile app which will run on Android and iOS.

To do so, we are going to create a useful utility which will make creating our custom Decorator easier. This utility can be found in the angular2-seed-advanced project in addition to more elaborate use cases for it. Let's start by looking at how this utility works so you can use it in your own apps.

1. Create a Decorator Utility

Decorators have been proposed to become an offical part of ES7. In the meantime, we will need the reflect-metadata shim loaded in our web app or included with your build setup (webpack, gulp, etc.). This shim provides the api to interact with our Decorator's metadata. In particular, it will load a global Reflect object we will use and define as const _reflect.

import {Component} from 'angular2/core';

const _reflect: any = Reflect;

export class DecoratorUtils {
  public static getMetadata(metadata: any = {}, customDecoratorMetadata?: any) {
    return metadata;
  }
  
  public static annotateComponent(cls: any, metadata: any = {}, customDecoratorMetadata?: any) {
    let annotations = _reflect.getMetadata('annotations', cls) || [];
    annotations.push(new Component(DecoratorUtils.getMetadata(metadata, customDecoratorMetadata)));
    _reflect.defineMetadata('annotations', annotations, cls);
    return cls;
  }
}

We define 2 static methods:

  • getMetadata
  • annotateComponent
You may be wondering why getMetadata is there since it doesn't look like it does anything and you are correct. It doesn't...yet. The details of annotating our Component via Reflect's api is tucked away in annotateComponent. For those wanting to learn more about Reflect, I recommended reading this. Additionally, the incredibly illustrious and well-versed Pascal Precht at thoughtram has written a fantastic in-depth article here which will help provide more background information on Decorators.

2. Create a Custom Component Decorator using our Utility

Here we are exporting a function named BaseComponent which will become the name of our custom Decorator. It accepts our Component's metadata and passes that into our Utility's annotateComponent method.

import {DecoratorUtils} from './utils';

export function BaseComponent(metadata: any={}) {
  return function(cls: any) {
    return DecoratorUtils.annotateComponent(cls, metadata);
  };
}

3. Finally, create a Component using our Decorator:

Now, instead of using Angular 2's Component Decorator, we can use our custom BaseComponent Decorator.

import {BaseComponent} from './decorators/base.component';

@BaseComponent({
  selector: 'sample',
  templateUrl: './components/sample.component.html'
})
export class SampleComponent  {
  public statement: string = 'Angular 2 is amazing. Even more so with {N}.';
}

At this point, our BaseComponent Decorator is not helping provide anything unique. Not yet anyway. You may also be wondering, why go to the trouble of creating a custom Decorator at all?

Do you really want to have conditional logic in every single one of your components that would swap your HTML templates with {N} XML templates? ... crickets ...
I didn't think so.

In the example above, our Web templateUrl: './components/sample.component.html':

<h1>{{statement}}</h1>

Remember earlier when we answered Yes to creating a separate NativeScript XML template for each HTML template?

The possibilities are endless with the rich variety of native UI Components provided by NativeScript, but here's one way we might create that HTML view in NativeScript XML using nativescript-angular:

<Label [text]="statement"></Label>

This will render a Label UI control native to the host platform, be it Android or iOS. You might recognize the [text]="statement" binding. Yep, that's just standard Angular 2 bindings.

Our *native* `Label` UI on both Android and iOS.
Note: Please take note to not use self-closing elements like <Label [text]="statement" />.
This is related to the Parse5DomAdapter noted here.

Ok, now let's make our custom BaseComponent Decorator do something interesting.

Use the NativeScript XML view when running the mobile app

Queue in our Decorator Utility. The goal is to teach our Component's to know which {N} templateUrl to use without disrupting our web development flow. A new service will be introduced, ViewBrokerService, which we will create momentarily. Since we will be using our handy utility for all of our custom decorators, let's make our adjustment there:

import {Component} from 'angular2/core';
import {ViewBrokerService} from '../services/view-broker.service'; 

const _reflect: any = Reflect;

export class DecoratorUtils {
  public static getMetadata(metadata: any = {}, customDecoratorMetadata?: any) {
    
    if (metadata.templateUrl) {
      // correct template for platform target
      metadata.templateUrl = ViewBrokerService.TEMPLATE_URL(metadata.templateUrl);
    }
    
    return metadata;
  }
  
  public static annotateComponent(cls: any, metadata: any = {}, customDecoratorMetadata?: any) {
    let annotations = _reflect.getMetadata('annotations', cls) || [];
    annotations.push(new Component(DecoratorUtils.getMetadata(metadata, customDecoratorMetadata)));
    _reflect.defineMetadata('annotations', annotations, cls);
    return cls;
  }
}

What is happening here?

  • If our component defines a templateUrl, we are going to shuttle it through ViewBrokerService.TEMPLATE_URL which will handle "brokering" the right view template for the right platform.
  • getMetadata now serves a purpose to keep our augmented capabilities tidy and isolated away from the details of the Reflect api. This allows us to focus on the special sauce that will make our custom Decorator tick with less distraction.

Create ViewBrokerService

This slim service provides a single static method, TEMPLATE_URL, which will be used to provide the proper path to a template based on a static runtime configuration setting, handled by CoreConfigService; created in a moment.

import {CoreConfigService} from './services/core-config.service';

export class ViewBrokerService {
  
  public static TEMPLATE_URL(path: string): string {  
    if (CoreConfigService.IS_MOBILE_NATIVE()) {
      path = path.slice(1); // remove leading '.'
      return `./frameworks/nativescript.framework${path}`; // this can be any path to your {N} views
    } else {
      return path;
    } 
  }
}

The path returned for your {N} templates can be any location in your codebase.
Here's a condensed view of the sample directory structure used throughout:

In this example, all NativeScript templates are contained in a nativescript.framework folder nested under a frameworks folder.
The path expands underneath the nativescript.framework folder to match the exact same path our Component's templateUrl defined, which was:

templateUrl: './components/sample.component.html'

With help from our Decorator, the ViewBrokerService will expand our Component's templateUrl to become:

templateUrl: './frameworks/nativescript.framework/components/sample.component.html'

That is, of course, only if your runtime configuration says so.

Create CoreConfigService

A pragmatic way to provide some static configuration options that can be set at runtime.

interface IPlatforms {
  WEB: string;
  MOBILE_NATIVE: string;
}

export class CoreConfigService {
  
  // supported platforms
  public static PLATFORMS: IPlatforms = {
    WEB: 'web',
    MOBILE_NATIVE: 'mobile_native'
  };
  
  // current target (default to web)
  public static PLATFORM_TARGET: string = CoreConfigService.PLATFORMS.WEB; 
  
  // convenient platform checks
  public static IS_WEB(): boolean {
    return CoreConfigService.PLATFORM_TARGET === CoreConfigService.PLATFORMS.WEB;
  }
  
  public static IS_MOBILE_NATIVE(): boolean {
    return CoreConfigService.PLATFORM_TARGET === CoreConfigService.PLATFORMS.MOBILE_NATIVE;
  }
}

The Final Stretch

With all the details in place, we are now ready to run (bootstrap) both of our applications.
We will need 2 separate bootstrap files, one for the web and the other for our native mobile app.

Web Bootstrap 

Our web bootstrap may look something like this:

// angular
import {provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';

// app
import {SampleComponent} from './components/sample.component';

bootstrap(SampleComponent, [])
  .catch(err => console.error(err));

NativeScript Bootstrap

We will use a different bootstrap file for our NativeScript app using nativeScriptBootstrap provided by nativescript-angular.

// nativescript
import {nativeScriptBootstrap} from 'nativescript-angular/application';

// config
import {CoreConfigService} from './services/core-config.service';
CoreConfigService.PLATFORM_TARGET = CoreConfigService.PLATFORMS.MOBILE_NATIVE;

// app
import {SampleComponent} from './components/sample.component';

nativeScriptBootstrap(SampleComponent, []);

Now when our NativeScript app runs, the templateUrl will be swapped out with the {N} view and Voila!
You are now using all the code from your web application in your native mobile app! A truly amazing feat.

The 2 unique considerations are:

  1. Create {N} XML template for each HTML template.
  2. Create a separate bootstrap file for your NativeScript app which sets a static configuration option used by your ViewBrokerService.

There's always one other thing

Say you want to utilize the same Component method for both your web view and {N} view. Depending on the specific control in use, you may need some conditional logic to determine what the user clicked on in the web vs. native mobile.

Here's an example using our Component:

import {BaseComponent} from './decorators/base.component';
import {CoreConfigService} from './services/core-config.service';

@BaseComponent({
  selector: 'sample',
  templateUrl: './components/sample.component.html'
})
export class SampleComponent  {
  public dogs: Array<any> = [
    { title: 'Greyhound' },
    { title: 'Frenchie' },
    { title: 'Brussels Griffon' }
  ];
  
  public selectDog(e: any, dog?: any) {
    if (CoreConfigService.IS_MOBILE_NATIVE()) {
      if (e) {
        // newIndex is a property of the SegmentedBar control event
        dog = this.dogs[e.newIndex];
      }
    } 
    
    console.log('Selected dog:', dog);
  }
}

Web template: './components/sample.component.html'
<ul>
  <li *ngFor="#dog of dogs" (click)="selectDog($event, dog)">{{dog.title}}</li>
</ul>

NativeScript template: './frameworks/nativescript.framework/component/sample.component.html'
<SegmentedBar [items]="dogs" (selectedIndexChanged)="selectDog($event)"></SegmentedBar>

The result. Web template using some CSS styling. NativeScript SegmentedBar as is.

To {N}finity and Beyond!

The advanced Angular 2 seed expands on the ideas presented here to provide a NativeScript option to the popular angular2-seed by Minko Gechev, the author of Switching to Angular 2.

You will notice that with the advanced seed, the NativeScript app is in a separate directory nativescript aside from the main web src directory. The web src is actually copied into the nativescript directory when the NativeScript app is run with these instructions. This is done for several reasons, but to list the most important:

  • Removes the need to process {N} specific modules in the main web build which uses gulp.

Keep an eye on the advanced seed for improvements to potentially move the nativescript directory inside the src directory alongside the main web source (to remove the necessity of copying the src). The build will be modified soon so only the specific code relevant for either platform web or native mobile would be built upon command.

Wednesday, March 16, 2016

Angular Material 2: Alpha preview!


On Tuesday, we released angular2-material alpha.0 - titanium-octopus, kicking off the public availability of the initial set of Angular Material 2 components.

What is Angular Material?

The goal of the Angular Material project is to build a set of reusable Angular components that implement Google's Material Design specification. We've already built a comprehensive set of these components with Angular 1; check out https://material.angularjs.org for demos and API docs. You can see these Angular Material 1 components in action on several Google products, such as Google Trends, Google Shopping Express, and your Google Search history.

Angular Material 2 vs Angular Material 1: What's different?

The new Angular Material 2 components are built completely new on top of Angular 2 so that they can take advantage of the improvements to both Angular and the web platform. We're also taking the lessons we learned building the current Angular Material to create something better than ever.

Can I use Angular Material 1 components in Angular 2 apps?

Sadly, no. To get the full benefits of Angular 2, you'll eventually need to upgrade to Angular Material 2.

We're working on cookbook examples to help you plan the upgrade from Angular Material 1 to Angular Material 2. These will be available closer to final release.

What does this alpha mean for Angular Material 1 Apps?

This new version for Angular 2 doesn't mean that Angular Material 1 is going away any time soon.

We know that many Angular 1 applications depend on Angular Material 1 for their UI, and that adoption of Angular 2 will take time. We are committed to both branches.

While bringing Angular Material 2 to feature parity, we are also actively working on maintaining and improving Angular Material 1, through regular minor and bugfix releases. We anticipate that Angular Material 1 will be supported for a long while.

What does the alpha process mean?

This alpha release is the first small step in an ongoing, rapid-iteration process. (So rapid, in fact, that we're already at alpha.1) Over the coming months, the team is going to be constantly adding new features, fixing issues, and incorporating community feedback. APIs will break, behaviors will change, and FABs will be flying everywhere! This process will let us hone-in on the best possible set of components for Angular 2 applications.

Check out angular/material2 on GitHub for more information on how to try out the new Angular 2 components, and stay tuned here and on Twitter for future announcements!

Tuesday, March 15, 2016

Advantages of Angular Templates

In modern web development, there are several techniques for building the components used by web applications. Angular's templates are authored using semantic HTML, encouraging a strong separation between how a component is structured and how it behaves. This is a design choice aligned with the Rule of Least Power.
the less powerful the language, the more you can do with the data stored in that language [...] I chose HTML not to be a programming language because I wanted different programs to do different things with it: present it differently, extract tables of contents, index it, and so on.
Because components are pure HTML, tools and developers can make smart assumptions about what components are and how they behave, and Angular 2 can do a lot of interesting things that would have not been possible if components used JavaScript instead. This article explores some of those benefits.

Swapping Implementations

One of the best things templates give us is a clear boundary separating the view layer from the rest of the framework. This enables us to completely swap the implementation of the view layer without breaking any applications. We did it several times while working on Angular 2.

For performance reasons, we would change how templates are compiled to try various optimizations and techniques. And we would do that without affecting our clients.

Performance is a very tricky thing. Often it is hard to know ahead of time how a particular technique will perform. So having the ability to experiment without breaking anyone is extremely useful. And it is key for building a fast framework.

This also means that the framework can have multiple implementations of the template compiler optimized for different use cases.

It is certainly possible to achieve the same result without using templates--you just need a well-specified boundary around the view layer. But it is a lot easier to maintain such a boundary when using templates.

Analyzing Templates

Being able to analyse or introspect templates is another consequence of the rule of least power. To see what I mean, imagine you use a data-access library like Falcor or Relay.

Normally, you would have to define all the queries needed by those libraries explicitly. And if you do not use templates, there is not much you can do about it. It is not possible, at least in a general way, to derive the queries from the JavaScript code rendering the components without actually running it.

The situation is different when the framework uses templates. They are much simpler, and more constrained than JavaScript, and, as a result, the data-access integration library could reliably derive the queries from the templates. And since the queries usually match the structure of the views pretty closely, we can remove a lot of duplication this way. To see how it can be done, check out [the second half of the talk Angular 2 Data Flow by Jeff Cross, Rob Wormald and Alex Rickabaugh.

Transforming Templates

Template introspection is extremely powerful. But what is even more powerful is being able to transform templates during compilation. This allows you to implement some syntax sugar in a matter of hours.

Can't we transform JavaScript the same way by, for example, implementing a Babel plugin? We can. But it is a lot harder. At least if we want to do it correctly.

You see, most templating languages just define the structure of the view. They have a limited set of well-defined side effects, and there are fewer order constraints. And that is why automatically adding new things to the template is unlikely to break the guarantees the templating language provides.

Here is an analogy to give you an intuition of what I mean here. Using templates to render components is akin to using this array literal [1,20,2,4] to describe the collection of the four numbers. Using JavaScript to render components is similar to using the following instructions to describe the same collection:

    array.push(1);
    array.push(20);
    array.push(21);
    array.pop();
    array.push(2);
    array.push(4);
Yes, the resulting collection is the same. The difference is that we can analyze the literal statically. So it is a lot easier to write transformations of it. And though in simple cases it is possible to analyze JavaScript to figure out what the resulting array will look like, it is not trivial. And it is not possible for an arbitrary set of instructions.

Declarative Animations/I18n/Accessibility

An ability to analyze and transform templates has a lot of practical applications. One of them is internationalization, where the framework can transform static text from one language to another without any runtime cost. Other examples include animations and accessibility.

Since in Angular these concerns can be handled by the template rather by imperative code, these features can be turned on or off to serve different users, for testing, etc.

Separating Dynamic and Static Parts

Another thing that using a templating language gives you is a clear separation of the dynamic and static parts of the view.

This helps you, the developer, quickly see the structure of the view, and how it can change.

But what is even more important is that the framework can do it too. It can easily see what parts of your view are static and optimize those. For instance, Angular knows that only expressions can change, and the rest of the markup is static. So after the initial rendering is done, the static markup is essentially free. It is a lot harder to detect static parts of the view when using virtual DOM.

It can also notify you about the structural changes. For instance, since Angular 2 knows when views get added or removed, it can animate those, without you having to do anything.

Building on Existing Technologies and Communities

Finally, a lot of people are already proficient with HTML and CSS, and they can leverage this knowledge to write html templates. On top of that, there is a rich set of tools around these technologies, and being able to use them when building applications is a huge plus.

In general, it is important to recognize that any big team will have multiple roles. And HTML templates are more inclusive of real-world workflow that includes designers, testers, and others who aren't deeply familiar with JavaScript, but who can interact with HTML templates directly or through tools.

Using Other Templating Languages

Since using templates requires the framework to have a well-specified boundary around the view layer, it is not hard to add support for other template languages. This allows us to build better integrations with other technologies. For instance, the Angular 2/NativeScript integration uses XML instead of HTML. But it is easy to go even further and add support for such languages as Twig or Haml.

Summary

Angular 2 embraces the rule of least power and uses templates because of this. This brings the following benefits:
  • The implementation of the template compiler can be swapped without affecting applications.
  • Templates can be analyzed and transformed to remove boilerplate and improve dev experience.
  • Static and dynamic parts of the view can be handled differently.
  • Internationalization and animations can be implemented in a declarative way.
  • Templates are built on top of an existing set of tools, and they are designer-friendly.

If you like this post, you can follow Victor Savkin on Twitter and read his personal blog.

Wednesday, March 2, 2016

Hosting Inclusive Angular Events: Ideas from AngularConnect

We care a lot about making Angular's community inclusive and welcoming for everyone. 
Guest bloggers Vicky Carmichael and Ruth Yarnit are part of the White October Events team that co-organises AngularConnect.  If you're planning an Angular meetup or conference, you might find this post helpful in increasing the reach of your event. Enjoy!  - Naomi


As an event organiser, you want your attendees to have an amazing time. You put a lot of thought into the content, the venue and the atmosphere – and these are all important – but your natural and unconscious biases may make it easy to forget about how your experience of an event differs from someone else’s.

There are lots of reasons an attendee may require additional support to ensure they have a great time at your event. Perhaps they have a disability or health condition that means they require special assistance to be able to access the event and enjoy it fully. Maybe they come from an underrepresented group within tech, and are experiencing a sense of isolation. Or they may be new to the industry and feel a little intimidated to be surrounded by more experienced developers.

This post outlines some of the measures the AngularConnect team are taking to improve accessibility at their conference, and offers some handy pointers for how you can implement these measures at your own Angular events. This is by no means an exhaustive list – we know there’s always more we could do. Please feel free to email us at hello@angularconnect.com if you have any comments or other ideas.

Code of Conduct

Having a Code of Conduct at your event demonstrates your commitment to ensuring all participants feel welcome, safe and comfortable without threat of intimidation or public embarrassment. Here are some tips if you’re implementing one for the first time:
  • Start with a template, and adapt it for your specific industry and event. Check out Angular’s Code of Conduct, which applies to all of the projects under the Angular organisation on GitHub and the Angular community at large, including IRC, mailing lists, and on social media.
  • Be sure to list specific examples of behaviours that constitute a violation of the code. For instance, the AngularConnect code includes the line: “Harassment includes offensive verbal comments, sexual images in public spaces, deliberate intimidation, stalking, following, harassing photography or recording, sustained disruption of talks or other events, inappropriate physical contact, and unwelcome sexual attention.” This makes it easier to identify offending behaviour as it happens.
  • Include clear instructions for what someone should do if they wish to report a violation of the Code of Conduct, and make sure all event staff are fully briefed on how to respond to such a report. AngularConnect staff wear brightly coloured t-shirts with the word “staff” or “organiser” on the back, so that they can be easily identified from afar by anyone needing assistance. Also provide details about how you will enforce your Code of Conduct.
  • Make everyone aware of the Code of Conduct. Link to it clearly on your event website, and announce it on the day(s). We include a mention of the AngularConnect Code of Conduct at the bottom of every marketing email we send. This year we also plan to display large signs at the event reminding people where the code can be found, and how to report a violation. Make it clear that you expect all delegates, speakers, organisers and staff to comply with the code at all times and in all event spaces.
  • Finally, don’t just pay lip service to your Code of Conduct. As event organisers, it’s our responsibility to use our judgement and take swift and appropriate action in the event of a violation of the Code of Conduct, and to send a clear message to our attendees.

Further Reading

Conference Code of Conduct
Codes of Conduct 101 + FAQ
Conference anti-harassment policy
HOWTO design a code of conduct for your community
Angular's Code of Conduct
AngularConnect Code of Conduct

Access Requirements

Making your event as accessible as reasonably possible will help ensure you’re not inadvertently excluding anyone from attending. People you should consider include wheelchair users and those with mobility impairments, people who are hard of hearing or deaf, people with visual impairments, and people with hidden impairments such as learning disabilities or mental health issues. Here are some measures you can take:
  • On your event sign up form, include a checkbox for attendees to let you know if they have any special access requirements, and a field for them to provide further information. Make sure you check the feedback in plenty of time to make any necessary arrangements at the venue, and reach out to the attendee directly if you need more information to be able to accommodate their needs.
  • When selecting a venue for your event, check that it’s fully wheelchair accessible. Consider whether it has step-free access, doorways wide enough to accommodate wheelchairs, elevator access to relevant floors, and dedicated accessible toilet facilities.
  • Have reserved seating at the front of the space for people with disabilities, such as wheelchair users and people with visual impairments to use, if they wish to.
  • Enquire whether the venue has hearing induction loops installed in the relevant spaces and, if it doesn’t, think about hiring them in. The venue may be able to put you in touch with a supplier. At AngularConnect we’re installing a hearing loop in both of the main track spaces for use by people with hearing aids.
  • Consider providing real-time captioning for talks. You can choose how to display this, but make sure captions are clearly visible to all participants. This is something we’re excited to provide at AngularConnect this year, and we’ve selected a service that provides attendees with a link that can be viewed and customised in the browser on their personal device. This service is not only helpful for people who are hard of hearing, but also those for whom English is not their first language, and anyone who finds it easier to take something in when they see it written down.
  • Make it clear to people considering attending that service animals such as guide dogs are welcome at the event, and offer to provide complimentary tickets to assistants of those with disabilities.
  • Invite participants to contact you with any access requirements they’d like to discuss, and commit to doing your best to accommodate them. If you need time to check whether you’re able to provide the assistance they need, you could offer to reserve their ticket in the meantime so that they don’t risk missing out.
  • A full-day (or longer) event surrounded by crowds can be overwhelming for some people. If you’re running a conference for an audience of hundreds, you may wish to create a comfortable “quiet zone” for those who need to take a breather. At AngularConnect last year we had ran mindfulness sessions in our chill out area for those who need a peaceful moment’s reflection. We got positive feedback about this and we’re looking forward to bringing the sessions back this year.

Dietary requirements

If you’ll be serving breakfast, lunch or dinner, you should offer at least one vegetarian option available as standard. You can aim to cater for more specific requirements (such as gluten free, allergies, Kosher, Halal, vegan etc.) with advance notice. Ask all attendees to let you know about any special dietary requirements at the point of registration. Be sure to label major allergens such as gluten or nuts on food packaging where possible.

Scholarship scheme

For paid events, you may wish to make extra efforts to open up your event to people who don’t have access to the funds to buy a ticket. One method for doing this is to run a Scholarship scheme where you set aside a number of free tickets to give away to individuals from underrepresented groups in tech or those facing economic and social hardship. If you have the budget, you could also consider covering their travel and accommodation expenses. Some sponsors may be willing to support a scheme like this financially.

To get set up, design a basic online form to capture applicants’ information, such as their name, contact details, location, and their reason for applying to the Scholarship Scheme. Have a look at the AngularConnect Scholarship Fund form for inspiration. Be sure to link to the form on your site and tickets page, shout about it on social media, and reach out directly to groups working with relevant individuals to ask if they’ll help spread the word. Include clear details about who should apply, how the process works, any deadlines, and how and when you will notify them of the outcome.

There’s no exact science to evaluating the applications, but it’s best done by a small committee rather than by just one person. You should aim to award tickets to people who would otherwise not be able to attend, and who can show how the knowledge they gain at the event will be useful to them in their ongoing career.

Summary

There’s an awful lot to think about when organising a conference or meetup. As a team, we try to be mindful of accessibility at all stages of planning AngularConnect, but we know there are always more improvements we can make. We hope this post has provided some food for thought for other event organisers, and we’d love to chat with you if you have comments or ideas for additional ways to make events accessible. Catch us on on Twitter at @AngularConnect, or email hello@angularconnect.com.