Why AngularJS Devs Should Use Meteor

Published May 18, 2015Last updated Aug 24, 2017

This article will go over the reasons he thinks AngularJS devs should try running Angular on Meteor. The post is based on the Codementor Office Hours hosted by Uri Goldshtein, who created the Angular Meteor library. 

Office hours with "angular-menteor"


Introduction

I started Angular-Meteor more than six months ago, and it was because I tried all kinds of backend frameworks (e.g. Rails, PHP) and I was very frustrated with the back-ends I’ve used before. I came from a .NET background, so I was used to having the full frame of support with the tools.  When I started using Angular, I felt suddenly everything became so much faster─stuff just worked great and everything was very logical. For me, it was very similar to WPF and .NET.

However, the back-end wasn’t the same. Everything was too slow to develop and I started going into the direction most Angular people always go, which is more about making the client site bigger.

In this article, I will go over 5 points:

  1. Why you should write AngularJS applications with Meteor. If you really study the platform, you can do almost anything and it’s open source. It’s all built on top of packages, so you can just replace packages and do whatever you want.
  2. Use your existing applications and all 3rd party libraries.
  3. Angular works natively on Meteor. I’ll show how we did that; how we’re syncing the data with Meteor. We’re basically doing the same thing as Blaze, but with Angular. There are no performance issues in the synchronization. Every bottleneck or something that you will have is not because of the connection. It’s just the global limits of those frameworks.
  4. You should check out Meteor and you will really enjoy that framework.
  5. For Meteor developers: Opening Meteor to more opinions helps the framework. After Meteor released their 1.0 version, everything works and they have this package of packages that just works. Meteor is getting more open and seeing the possibilities that happen in those years in the JavaScript world.

What is Meteor?

Meteor is an open-source platform for building web and mobile apps in JavaScript, which is a big difference. The JavaScript back-end world is getting really busy. Now there are more solutions, and there’s Angular 2.0, which is very exciting as well. The most important trend is that front-end developers should start looking at back-end code. We can categorize a lot of those things that are happening on the back-end as services.

Meteor is akin to your infrastructure team, and it takes care of everything about communication for you, but it’s also completely open source and you can deploy it on your own servers.

The Community

In terms of community, here are some data about Meteor:

  • Over 150 meetup groups around the world – meteor.meetup.com
  • Over 5000 community – authored packages – atmospherejs.com
  • Ranked #10 on GitHub (just passed Backbone, will soon pass Rails)

As you can see, Meteor is growing super fast,if you are traveling all over the world you can talk in other places and there’s a lot of community packages. The community is huge like any other ecosystem, and Angular-Meteor is a part of that community. Even if the core development team doesn’t support something, it doesn’t mean it’s not there, so people use to say you can’t use Angular & Meteor together, but this is no longer true now that you have the Angular-Meteor library.

Why AngularJS Devs Should Use Meteor

The last solution that I used was HapiJS, and it’s a really good framework that, in my opinion, is much better than Express.js. Both Happy and Express do very particular things. However, I think that AngularJS is very opinionated, so it needs something more than HapiJS or Express.js.

MEAN.js vs Meteor

In my particular opinion, the MEAN.js promise was to make back-end code simple enough for front-end developers to use. This is a little bit of a broken promise. It seems easy enough at the beginning, but once you get into more logic, things get harder. Meteor, on the other hand, delivered that promise of making backend code easier.

For example, the first line in the slide above is the simplest API that you can do to just start working with Angular-Meteor.

$scope.parties = $meteor.collection(Parties);

If you’re an AngularJS developer, that’s the only thing you need to change in your code, and it will replace your HTTP service or your Firebase service. I take a lot of ideas from the Firebase service because I think they’ve done a great job of integrating into Angular.

Because we’re integrated as a $meteor service, you can just inject it in your application. You can work with UI router and with you existing applications and your existing third party libraries.

Modern Apps are more than client-server Ajax calls

Large applications like Gmail, Facebook, etc, use an architecture that makes a lot of sense for me, especially since I am a .NET developer. You have a local cache you work with, where everything is saving to there, and your infrastructure takes care of syncing that with the back-end.

Meteor’s goal is to be the architecture for you to write Gmail or Facebook quality apps, and it’s all open-source. Meteor’s infrastructure team itself takes care of the core components, which I think is great.

Meteor’s distributed data protocol, also known as DDP, is a standard protocol just like REST but for Realtime over sockets. We can see more and more companies that go into that type of architecture. There are implementations of DDP for iOS, Go, Ruby, and many more. You can start working with that protocol and your own technology, and just gradually move Meteor parts into your architecture.

Libreboard

A good solution that shows how Meteor is radically simpler is Libreboard. It’s just an open-sourced Trello replica developed by two guys from two different countries in two months, and it works exactly like Trello. Again, it’s open-sourced so you can look at the code and everything just to get a feel of how awesome Meteor is.

Angular-Meteor

Real-Time Data Service

The first thing we did in Angular-Meteor is the Real-Time data service. You have a collection, you have the data that exists on the server, and the only thing you need to do to bind it into your scope is this first line here:

$scope.parties = $meteor.collection(Parties);

You just call the service $meteor.collection and bind it into the parties (the plain Meteor object). The parties on $scope.parties is a plain Angular object.

At any rate, that one line is the only thing you need to do to sync the data, as it will auto-bind instantly and every change you make will reflect instantly.

However, sometimes you wouldn’t want to do that all the time. Sometimes you don’t want to watch over the Angular part, but you want to explicitly update the client so it would listen to all the reactive changes from Meteor, and push the updates from the client explicitly.

$scope.parties = $meteor.collection(Parties, fales);

$scope.parties.save(newParty).then(function(changedDocs){
  console.log('Yaay!', changedDocs);
}, function(error){
  console.log('Oh No!',error);
});

You can do this by canceling that auto-bind of the Angular part in the code above, and just explicitly save new parties or change the parties in any way you wanted (just save everything at once). If there was an error, you get a promise. If you haven’t had permissions to do it, you will get an error. Or, you will get the actual change that happened and the confirmation.

Furthermore, Meteor takes care of watching the data and syncing it with the client. When we do $scope.parties = $meteor.collection(Parties) , we need to watch two types of changes: one is Meteor changes, and the other is the Angular scope changes.

In terms of Meteor changes, it watches over that parties collection which is registered at  Parties = new Mongo.Collection(“parties”);.

This happens when a plain JavaScript file exists in the root of the project. Any JavaScript file that you don’t put on Meteor or you don’t put on the client folder or on the server, it still exists on both the server and the client. Meteor has a big process that copies your code and distributes it also to the client, whether it’s code or whether its web/mobile, and to the servers. So basically Parties = new Mongo.Collection(“parties”); registers the JavaScript object that lives everywhere.

Because Meteor gives you the mini Mongo, which is the Mongo API on the client, you can do every action on parties on the client and on the server, and it will be exactly the same syntax as the Mongo API syntax.

Meteor will watch over the database to see those changes through the DDP protocol. The DDP protocol is very easy, and also little bit similar to the Object Observe API. It watches a collection and it gives you an API that basically lets you know when things are changed, updated, or inserted (through changedAt, updatedAt, and insertedAt). In other words, it’s a very simple API that gives you a log of everything that happens and happened, so you can react into those changes.

In $scope.parties = $meteor.collection(Parties), we’re watching all of this API and we’re updating just according to the updates we get for Meteor. So we get a changedAt at a particular party and we just update those parties in $scope.parties. We can “removed at” a particular party and we move just that particular party.

The second part is we need to watch over the scope parties, and we do that with a modified watch of Angular. You can see how this works from the code from Angular-Meteor project

function setAutoBind() {
  if (auto) { // Deep watches the model and performs autobind.
    ngCollection.unregisterAutoBind = $rootScope.$watch(function () {
      if (ngCollection.UPDATING_FROM_SERVER){
        realOldItems = _.without(ngCollection, 'UPDATING_FROM_SERVER');
        return 'UPDATING_FROM_SERVER';
      }
      return _.without(ngCollection, 'UPDATING_FROM_SERVER');
    }, function (newItems, oldItems) {
         if (newItems == 'UPDATING_FROM_SERVER')
         return;

         if (oldItems == 'UPDATING_FROM_SERVER')
           oldItems = realOldItems;

         if (newItems !== oldItems) {
           diffArray(oldItems, newItems, {
             addedAt: function (id, item, index) {
               ngCollection.unregisterAutoBind();
               var newValue = ngCollection.splice( index, 1 )[0];
               setAutoBind();
               ngCollection.save(newValue);
             },
             removedAt: function (id, item, index) {
               ngCollection.remove(id);
             },
             changedAt: function (id, setDiff, unsetDiff, index, oldItem) {
               if (setDiff)
                 ngCollection.save(setDiff);

               if (unsetDiff)
                 ngCollection.save(unsetDiff, true);
             },
             movedTo: function (id, item, fromIndex, toIndex) {
               // XXX do we need this?
             }
           });
          }
        }, true);
      }
    }

What we are actually doing is here is watching over our ngCollection. When we did a new collection, we actually created an ngCollection that holds those parties, and we’re watching over it. The diffArray function  gives us basically the same API as Meteor gives us, (e.g. with the changedAt, removedAt and editedAt), but on the other direction from Angular. Finally, we will update from Angular to Meteor on the server automatically. 

However, when we send a false in $scope.parties = $meteor.collection(Parties, false), we’re just canceling the watch and not watching over the scope parties anymore, but we’re still watching over the Meteor changes. This makes your app more performant. This actually makes Angular 1.0 & Meteor work much more similar to Angular 2.0, because Angular 2.0 has only one-way data binding instead of a two-way data binding.

However, if you do want to update from the client, you just explicitly do it. For example, if you click on a save button you would call save. We have an API reference where you can look and you can see what are all those functions are. You’ll see that the save function just saves all the collection if you don’t send anything. If you send an object, then it will save that particular object. If it’s a new object, it will edit it. It’s a very simple API.

Updating from the Angular side to Meteor

As you can see in the Angular-Meteor code, when we’re sending something like $meteor.collection(parties). Parties are Meteor’s Mongo collection. It’s an object that Meteor gives us. Mongo collection exists and this is Meteor’s thing, where it holds a Mongo cursor. This cursor in Meteor is reactive, and Meteor watches over Mongo. This means I want to not get all the collection, but I want to get just the first five results, or I want to get the first five results sorted by a first name. Meteor watches over the cursor, so it will update only those five objects and it will return those object sorted by something. So we actually extract that cursor from the parties and we observe it. 

Again, this is the API that actually reflects the DDP protocol. You can see that when we watch over that cursor, we get editedAt, changedAt, movedAt and removedAt and then we’re just updating our Angular array just based out of that.

If you want to know more about the Mongo cursor, I would suggest going to the Meteor docswebsite. The best way to look at it, is we have in step twelve in the tutorial, we have Search, Sort, Pagination, and Reactive Vars. This is an important chapter that worth to read.

OAuth, Accounts, and Security

Meteor is great for doing authentication, and Angular-Meteor also supports OAuth in a easy way. Once you’re logged in, the user can exist anywhere. You can just access the user and easily see what permission he has. It can exist under root scope or as a service if you want.

If you have roots in whatever router you use, you can also use a promise to make sure that the user has permissions to that, and then go into that route after the user logs in.

Also, you have services that you can call: meteor.loginwithpassword, meteor.loginwithfacebook, meteor.loginwithtwitter, which makes login super simple.

Finally, Meteor provides a UI, if you don’t want to do your custom forms, Meteor gives you different forms you can work on. You can just edit with one command line and you have everything you need for OAuth. I did a project in Angular before called ng-Secure because we had enough of doing the same thing in OAuth and Angular again and again, and now I feel like finally it’s solved with Meteor.

The Future of Angular-Meteor

Our biggest step for Angular-Meteor 1 is actually better test support. You can test both your Angular apps and Meteor power the best way you can, but we’re trying to figure out what’s the best practice to test both of them together. When we finish doing that, we’ll release 1.0. I think the API is already solid. 

 Angular 2.0 is also very exciting because we’re seeing that Angular is going in React and Blaze’s direction in terms of changing to one-way data-binding. Angular is also doing away with their scope data, which means the data that you’re working with will be whatever data you want to use in Angular 2.0 (e.g. Firebase data.) This makes the syncing much easier, improves performance, and also makes Angular fit more naturally into the Meteor set.

What we are doing in Angular-Meteor is making Angular 1.0 behave a little bit like Angular 2.0, because when we’re watching over the Angular array, we’re actually just here to get what’s added and then we’re reverting the change. And we will later get that change from the Meteor Mongo, from Meteor. But it makes the once source of truth not the scope data, but the local database. This philosophy is much more similar to Angular 2.0 than Angular 1.0, so we’re already doing that here. So I think using Angular-Meteor give you a little bit of the philosophy already of Angular 2.0 in a way.

Finally, in the future you can render AngularJS on the server side. It basically means that you can define the AngularJS service and use it everywhere. You can use it on your server-side code, client-side code, and even sync the data of that service everywhere. We have more things we want to add to Angular-Server like server-side rendering, server-side digest cycle, and more.

Part 2: Q&A with Uri – Blaze vs Angular-Meteor, would Meteor support postgres, and more.

Discover and read more posts from Urigo
get started
Enjoy this post?

Leave a like and comment for Urigo