I created the same app in React and Vue (Part 2: Angular)

After creating the same app in React and Vue, it’s only right that we throw Angular into the mix!

Sam Borick
Sep 8, 2018 · 8 min read

Not read Part 1 yet? Check it out here.

Update: Hello! I’ve created something called The Weekly Project Club. Every week you’ll get a project idea in your inbox. You can work on solving problems, and you’ll have the help of the whole club to keep you on track.

If you’re looking for a way to try out React, Vue, and Angular, you can join for 3 weeks and try each one out! It’s a great way to test drive a framework.

To learn more and join The Weekly Project Club, click here.

I use Angular at work every day, but in the JavaScript world one can’t help but hear about all the other frameworks out there. I also love comparing apples to apples! So when I saw Sunil Sandhu’s article on React vs Vue, I had to reach out! So here we are, React vs Vue vs Angular!

How do the apps look all together?

Image for post
Image for post
Player 3 Has Entered The Game

Just like in Part 1 the css is nearly identical to the other two, except for where they are located.

Image for post
Image for post

This Angular app is generated by the Angular CLI (Command Line Interface). Since Angular is frequently shortened to ‘ng’, the command to make this app was ng generate ng-todo .

Compared to Vue and React, Angular has a ton of files. One big reason for this is that while Vue puts everything for one component into one file, and React breaks out the CSS into its own file, Angular puts the css in one file, html in another, and the component code in another. While we can put all these into one file, it’s considered best practice to keep them separate.

Another reason for all the files is that Angular uses TypeScript. TypeScript is “a superset of JavaScript which provides optional static typing, classes and interfaces”. Lets unpack that a little bit.

Image for post
Image for post

TypeScript is really just adding a bunch of stuff on top of JavaScript. If we write a line of JavaScript in our TypeScript code, it will work just fine. What TypeScript lets you do is easily make classes, and enforce their usage.

In our project, we make a ToDo class:

export class ToDo {  constructor(item: string) {
this.Item = item;
Item: string;

This class doesn’t do a whole lot by itself. Where the power comes in is that we can write functions that require a ToDo, and the TypeScript compiler will yell at us if we try and give it anything else.

For Example:

function PrintToDo(myToDo: ToDo) { //the argument is of type ToDo
//this will generate a compiler error
this.PrintToDo("not a ToDo type")
//this will not
this.PrintToDo(new ToDo("a real ToDo"))

Of course we can do this with any type we want, not just classes:

function PrintString(myString: string) {
}//this will generate a compiler error
this.PrintToDo(new ToDo("not a string type"))
//this will not
this.PrintToDo("A string!")

TypeScript is just JavaScript, except it will throw type errors sometimes and prevent silly mistakes that would become runtime errors in just JavaScript.

As an application becomes more complicated, classes like this really come in handy! They serve as a good model for a real life thing, like a Product, Job or Person. In the Angular world, we refer to them as Models.

How do we create new ToDos?

Here’s our ToDoComponent:

Image for post
Image for post
ToDoComponent (Full Code)

Most what’s going on in this component has to do with styling and the input form. We’ll get to those in a bit, so let’s focus in on the ToDo list itself

Image for post
Image for post
ToDoComponent (Abbreviated)

When we get down to it, our list component is just a list of ToDos! ngFor can take our list and display each item, just like a foreach would. The big difference here is that Angular will handle updating for us! When we get some valid input, all we need to do is pass the string into a new ToDo object, and add it to our list. Angular takes care of the rest!

this.ToDos = this.ToDos.concat(new ToDo(this.Input));

That’s it! We also want to be able to make sure the user isn’t submitting an empty ToDo, so how do we prevent that?

Angular Form Validation

Instead of checking for an enter keypress, or checking the string content ourself so that we can throw an error, we can use Angular Forms to do that for us. If you look at the full ToDoComponent, we declare a form element,

<form (ngSubmit)="addItem()" #todoForm="ngForm">

That ngSubmit binding will trigger either when the submit button is pressed, or the user presses enter! It can also only be triggered when the form is in a valid state.

An ngForm also creates a component member variable for each input in a form, in this case called name. We can check what state that input is in, and show errors or other helpful messages depending. In this case we use valid, pristine, and we also keep track ourselves of wether or not the form has been submitted before.

Fun fact, we can also write custom validators for Angular! We don’t need them here, but we could have a form that knows how a phone number should be formatted, and do all the validation for us! Neat, right?

That takes care of our list, but what about actually displaying the ToDo?

Here’s our ToDo Item component:

Image for post
Image for post
Our ToDo Item Component

How do we mutate data?

In Angular, all we need to do to display some data is two things:

  1. Have a member in our component, in this case ToDo
  2. Reference it in the template with curly braces {{ToDo.Item}}

And that’s it! When we change ToDo.Item at all, Angular will update the view for us. React doesn’t really provide those hooks, because calling setState is going to re-render the component for us anyway.

Communicating with Components

Since this component is only concerned with displaying a single ToDo, the ToDoComponent needs to be able to give the ToDo Item component a ToDo to display! We also need to be able to tell ToDoComponent that the user has clicked the ‘delete’ button. Angular accomplishes this with ‘Inputs’ and ‘Outputs’

Inputs are very simple, they can be any type we want, and will be bound for us! In this component we just have a ToDo as an input. We tell Angular a particular member is an input by putting the @Input() decorator in front it.

@Input() ToDo: ToDo = new ToDo(""); 

Then our parent component just has to pass the ToDoItem component a ToDo like this:

<ToDoItem [ToDo]=”ToDo”></ToDoItem>

Then we just use a binding to display our ToDo!

Outputs are a little different. An Output isn’t just some data, it’s also an event to trigger whatever is watching for that output. Angular Inputs can be any type (like a string), but Outputs must by of type EventEmitter. EventEmitters emit a value though, which can be of any type we want! So if we wanted to output a string we would just create a decorated member like this:

@Output() Example: EventEmitter<string> = new EventEmitter();

And a parent component can subscribe to the event like this:

<ExampleComponent (Example)="exampleHandler($event)"></ExampleComponent>

Now that we’re armed with the knowledge of outputs, how do we delete a ToDo?

Deleting a ToDo

We don’t need to pass anything up from our ToDoItem component, we just need to trigger an event. Typescript needs to know what type our output is, but since we don’t care, we just make it any, so our Output looks like this:

@Output() Deleted: EventEmitter<any> = new EventEmitter();

We still need to trigger this event within ToDoItem. We’ve got a nicely formatted div that looks like a button form Part 1, we just need to hook a function up to the click event.

<div class="ToDoItem-Delete" (click)="deleteItem()">-</div>

Then deleteItem calls .emit() on Deleted:

deleteItem() {

and Angular will pass the event up to ToDoComponent.

Back in our ToDoComponent, we’ve bound the deleteItem function to our ToDoItem component. We also pass it the index of the current ToDo, so we know which one to delete.

<div *ngFor="let ToDo of ToDos; index as i" >
<ToDoItem [ToDo]="ToDo" (Deleted)="deleteItem(i)"></ToDoItem>

Then all we need to do is remove the ToDo at that index, and Angular will update the display.

deleteItem(i: number) {
this.ToDos.splice(i, 1);

There we go, one ToDo list application!

Even a tiny Angular app has a lot more going on than a React or Vue app. The really nice thing about Angular though is that most of the functionality you need is within Angular itself. Angular includes page routing, protecting access to pages, http calls, module lazy loading, and a whole lot more. A heavyweight framework has a big learning curve. However, the upside is that I rarely have to go outside Angular to find a solution for what I need.

When I’m not writing Angular, I like to help people figure out what programming language they should learn. There are a lot of different priorities to think about when picking a JavaScript framework. That’s why I created PickAFramework.com. I write articles about making big technical decisions, and help people make their own decisions.

If you’re struggling with whether to use React, Vue or Angular in your next project, please consider signing up for my email course. I talk about the methods you can use to pick a framework besides just comparing the code. It’s totally free and you can unsubscribe at any time.

Learn more about Feature Fishing here.

Thanks for reading! Thanks to Sunil Sandhu for making this all happen! Here’s a link to Part 1 if you haven’t read it yet. You can find the source code here on Github.

JavaScript In Plain English

New articles every day.

Sign up for The Best Bits

By JavaScript In Plain English

A weekly round up of the best content from In Plain English, handpicked by our Founder @sunilsandhu Take a look

Create a free Medium account to get The Best Bits in your inbox.

Sam Borick

Written by

Hello! I help people advance their programming careers with helpful advice. I’m Always open to answering questions. He/Him

JavaScript In Plain English

New articles every day.

Sam Borick

Written by

Hello! I help people advance their programming careers with helpful advice. I’m Always open to answering questions. He/Him

JavaScript In Plain English

New articles every day.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight.

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox.

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month.

Get the Medium app