loading...

Angular Apps in TypeScript or Dart?

jvarness profile image Jake Varness ・6 min read

Edit: if you are new to TypeScript syntax, you might find this article by @abelagoi helpful. If you're new to Dart, I'll try to write something about Dart since nobody else has written about it yet :)

Edit2: Dart for Beginners

In a never-ending struggle to determine which language that compiles into JS is best, Google makes everything even more confusing by offering many ways to write Angular apps. The two main ways you can write Angular apps is in either TypeScript or Dart.

That being said... What should you use? Let's compare what developing the Tour of Heroes application is like in TypeScript as well as in Dart.

The Languages

TypeScript is a typed superset of JavaScript that is built and maintained by Microsoft. You can think of it as JavaScript but with proper types. In TypeScript, you can define interfaces, create classes, all while having first-class support for accessing your favorite JavaScript libraries. You can write JavaScript in your TypeScript code and it will work as expected.

This is extremely important because if you have a favorite NPM library that you want to keep using, you can write the code in TypeScript exactly as you would in JavaScript and everything works smoothly.

Dart is a strongly typed language (required as of Dart 2.0) created and maintained by Google, with first-hand asynchronous support. It can be compiled into JavaScript, but there are some quirks that you need to be aware of, and unlike TypeScript, support for calling JavaScript libraries happens through interoperability libraries built into Dart.

If you have a favorite NPM library that you love and you want to keep using it for your Angular application, you might be tempted to just use TypeScript instead. I personally wouldn't blame you, as interop'ing between Dart and JavaScript doesn't sound particularly great.

However, the Dart Language comes packaged with pub, which allows you download reusable packages from a centralized repo, just like NPM. Packages in pub are categorized to show you that the library will work with web, Flutter, or server/command line development, so if you see a library that only works for Flutter, you probably don't want to use it, nor could you (I might make another post about Flutter later, but we'll see).

Creating a Project

Both the Dart version of Angular and the TypeScript version of Angular offer command line interfaces, and it's pretty easy to make a new project.

For Typescript, use NPM:

$ npm install -g @angular/cli
$ ng new my-angular-project
Enter fullscreen mode Exit fullscreen mode

For Dart, use pub:

$ pub global activate angular_cli
$ ngdart new my_angular_project
Enter fullscreen mode Exit fullscreen mode

Notice that for the Dart the project name uses underscores instead of hyphens. It is considered a convention to use underscores when naming a Dart package or project.

One other thing you might notice is that if you type ng --help vs ngdart --help, ng has a laundry list of things that it can do, whereas ngdart has three commands available: help, generate, and new.

When a project first gets created, you'll notice a lot of distinct differences between the TypeScript and the Dart projects. In TypeScript, you'll notice there is a src/ folder and an e2e/ folder, where your project source and end-to-end tests exist respectively. In Dart, you'll instead have a web/ folder containing a small amount of HTML necessary for your project to run, and a lib/ folder where all of your Dart source exists. For Dart projects, having all of the Dart source in the lib/ folder is a common practice.

To start the project in TypeScript you can type:

$ ng serve
Enter fullscreen mode Exit fullscreen mode

To start the project in Dart you can type:

$ pub serve
Enter fullscreen mode Exit fullscreen mode

Writing Code

I've pretty much made it through a lot of the Tour of Heroes tutorials in TypeScript as well as in Dart.

If you're looking through the two codebases, one of the things you might notice is that in TypeScript, Angular has support for modules, which helps drive a lot of dependency injection/inversion within an Angular project, and Dart does not. I personally didn't find this to be too cumbersome because a lot of DI principles can be achieved in Angular Dart by using directives and providers, but the modules in TypeScript do help keep your code concise, and it helps to separate responsibilities. You might notice that in the Dart codebase, my AppComponent pretty much acts as the AppModule linked above. It has to handle route configuration and be aware of a couple of different providers and directives that it wouldn't otherwise need to be aware of.

Fortunately though, the Angular Dart team is working on getting dependency injection added to version 5.0 of Angular Dart. Again, a lack of DI support isn't convenient, but it doesn't stop you from writing code.

One thing you might notice as well is that the code between the two codebases has some striking similarities. Looking at just the HeroDetailComponent in each project, you might notice only a few differences between the TypeScript version and the Dart version. It's mostly differences in syntax at this point.

For example, the constructor for this component in Dart looks like this:

HeroDetailComponent(this._heroService, this._routeParams, this._location);
Enter fullscreen mode Exit fullscreen mode

Whereas in TypeScript it looks like:

constructor(
    private heroService : HeroService,
    private route: ActivatedRoute,
    private location: Location
  ) {}

Enter fullscreen mode Exit fullscreen mode

The main difference here is that TypeScript has keywords to tell you what is private. In Dart, if a member is prefixed with _, it's a private field.

Another thing you might notice is that with regard to methods, the TypeScript methods look pretty simple:

  ngOnInit() : void {
    this.route.params
      .switchMap((params : Params) => this.heroService.getHero(+params['id']))
      .subscribe(hero => this.hero = hero);
  }

  goBack() : void {
    this.location.back();
  }

  saveHero(): void {
    this.heroService.updateHero(this.hero).then(() => this.goBack());
  }
Enter fullscreen mode Exit fullscreen mode

Each method returns void. In Dart, since all of the methods within the component are asynchronous, Dart requires a little more syntax:

  @override
  Future<Null> ngOnInit() async {
    int id = int.parse(_routeParams.get('id') ?? '', onError: (_) => null);
    if (id != null) hero = await _heroService.getHero(id);
  }

  void goBack() => _location.back();

  Future<Null> save() async {
    await _heroService.update(hero);
    goBack();
  }
Enter fullscreen mode Exit fullscreen mode

In Dart, when you have an asynchronous method defined, you cannot return void. Instead, the way that you would define a void async method in Dart is to make it return Future<Null>. This just tells consumers that while this method is an async method, it doesn't return anything.

Application Look and Feel

I honestly couldn't tell you the difference between the two. Both applications work the same way.

In TypeScript:

ts

In Dart:

dart

The differences are shocking, I know.

The tooling within the Dart application made me forget all the cool tools that I had in TypeScript, with the exception that I wasn't able to put a delay in my services to mimic a real environment. Whenever I tried, I kept getting an exception and just gave up trying to make the app feel real.

Edit 3: I actually got it to work eventually. The issue was that I wasn't using Future.delayed properly. I was just putting my mock heroes list in as the second param rather than using a closure or function like they suggested in the tutorial.

In both instances, I was able to change code, save, and reload the apps with my changes being reflected without having to start or stop the server. I felt like I had enough resources and libraries at my disposal to accomplish what I needed to (granted, it was a tutorial where all the libraries have already been developed, but ya know...).

Overall

Honestly, I don't really see much of a difference face-up just doing the tutorials. I would say that if you have a lot of existing JS libraries that you like using and want to continue using for your Angular app, you should use TypeScript. If you want to learn something new and you don't like JavaScript, don't be afraid to write your app in Dart.

I hope that you enjoyed this overview of Angular Development using Dart and TypeScript. Have you made an app in Dart or TypeScript? What did you like about either? Let us know!

Discussion

pic
Editor guide
Collapse
fly0c8 profile image
fly0c8

I've gone through both tutorials and I find the Dart version much more intuitive, especially when it comes to async/await vs. Rx. Dart is the better language and the tooling is better too. And then there is Flutter, which seems like the best thing since sliced bread when it comes to mobile development.

That said, the community seems to be nonexistent. That's why I'm forced to use Typescript at my company instead.

Collapse
stormingorman profile image
Brian Gorman

Dart is a much superior language to Typescript from an OOP perspective but also, and maybe more importantly, because of their collection and stream api. Also, dart has a lot of the niceties found in modern languages like optionals and class-as-interface ..

The interoperability between Typescript and Javascript is one of the biggest weaknesses of Typescript in my opinion. A lot of the main problems of javascript can bleed through and coexist with typescript. Not unlike how C-code is also valid inside of C++ code .. and C++ suffered from the same low level caveats found in C.. It was a mistake to try to put OOP on-top of C and it is still a mistake to put OOP on-top of JS... But they did it for the same reasons.. you can use all your old C libraries ! Code is much more stable and cleaner if these low-level problems are abstracted away. With a strongly typed language with optionals, bugs and crashes can often be discovered at compile time. And as you point out, the async support is first class.

Dart's functional support is awesome... its Collection API and optionals makes it where you rarely need to ever explicitly write an if statement or a for loop.. It is strongly typed with many of the bells and whistles of modern languages like Swift and Kotlin. I've developed client and server side code with both typescript and dart and in my view there is no question which is the better language.

Collapse
graphicbeacon profile image
Jermaine Oppong

Thanks Jake.

I was googling the angular_cli tool and that got me here. I had read this post a while back but forgot all about it. I wished I remembered this before making the AngularDart tutorial series on my YT channel.

Collapse
jvarness profile image
Jake Varness Author

If you want to use this article to inspire another video feel free 😊 although this is pretty old and was using Angular Dart 4.X. They've since added dependency injection and all that.

Collapse
stargator profile image
Stargator

By the way, Angular 5 will have the Module system and it will be optional. Already implemented in the development version of Angular 5

Collapse
jvarness profile image
Jake Varness Author

Angular Dart right? Yea at the time that I wrote this they hadn't implemented it yet!

Collapse
stargator profile image
Stargator

Angular Dart version 5, yep. Left that part out.

Collapse
zaatas profile image
Matthew Rockwell

Jake, many thanks for this article. Cleared a few things up for me. I've built 2 flutter prototype apps; enough to prove to myself Darts/Flutter's worthiness. Yes, it's a keeper. That said, I don't know squat of Angular. I've been using react/vue for browser work and java/kotlin (I really like kotlin) for the server side. So, it's time to learn Angular for js and dart... Thanks again.

Collapse
jvarness profile image
Jake Varness Author

Glad you enjoyed this post Matt! Kotlin is definitely on my list of languages to learn!

Collapse
bobrov1989 profile image
Vitalii Bobrov

Great post! Just few issues with code examples:

  • don't use Null as return type, as it's low-level type you don't want to use in 99% of cases -so instead Future<Null> use Future<void>
  • It is a good practive to keep ngOnInit sync = you can extract the async setup into separate method and call it wrapped in unawaited() for example
Collapse
alinawxn profile image
Xiaonan Wang

WOW I was just googling about angular dart and your name popped up! How's it going!

Collapse
jvarness profile image
Jake Varness Author

Hey Alina! Doing great! 😁 How's it going with you?

Collapse
stargator profile image
Stargator

This is perfect Jake, it crossed my mind to do something similar when I went through both tutorials. Great job!