Meteor.js blog written by @elfoslav

Meteor method vs. publish 16-10-2017 (d-m-Y)

I have been searching for Meteor publish versus method usage and I have found this interesting discussion on Reddit: https://www.reddit.com/r/Meteor/comments/4b89x5/should_meteor_methods_only_be_used_for/ 

One comment was the one I was searching for:

Always using a publication for getting data adds an absolute ton of load to your server cpu+memory if you've got a lot of publications. It'll look and work great during development but really limit your scaling per server instance. As a rule of thumb, only subscribe to a publication if you need the data to be reactive (keeps updating in realtime). So for chat messages you may want a publication, but for getting a users profile data, that doesn't have to be reactive at all so you should use a Method. If you like always grabbing data from MiniMongo you can use a Method and store it's result in MiniMongo manually.

Think of Methods as similar to a REST call, you want some data one time and you grab it. If you want the data to keep flowing in automatically when things in the db are changed, you subscribe.

Click to see comments


Meteor.js vs. MEAN stack 08-07-2015 (d-m-Y)

Disclaimer: This is my personal view on Express/MEAN and Meteor. I have used both for developing applications.

This image (borrowed from Comparing Meteor.js and the MEAN stack) depicts exactly what the MEAN stack is and what Meteor.js is:

The MEAN stack

The MEAN stack is just MongoDB, Express, Angular and Node.js bundled together. The main problem with this stack is that Express.js is too lightweight and programmmer has to do a lot of things on his own. For example authentication and registration can take a few hours to implement in Express.js. You have to learn and understand Angular.js which is not so easy to learn. 

What about minification of JavaScript and CSS? You have to do it by hand in Express.

What about building real-time applications? Handling sockets by hand is out of fashion but you have to do it in Express.

Meteor.js for the win

Meteor handles all the issues mentioned above and even more! Do you want to show your application to the world but you don't want to pay for hosting yet? Meteor provides free hosting for Meteor apps on meteor.com subdomain. You can deploy your application with one command and your application is on the internet:

meteor deploy yourappname

Cool!

Meteor has a lot of packages built by its community. You can basically build your application just by putting packages together. Do you need authentication and registration? Just add a package for it. Do you want to use LESS or CoffeeScript? Just add packages for it...

Meteor has a lot of features, you can read this article: Building pure JavaScript applications or watch 11 minutes short/long video:

Don't waste time with technologies that are difficult to learn and where you have to do a lot of work by yourself. Meteor is easy to learn. It's the easiest technology to learn and the most powerful. Just try to write an application with Meteor and you will see. You will be surprised how simple Meteor.js is.

Click to see comments


How to sort collections in Meteor 10-06-2015 (d-m-Y)

I thought it's clear how to sort collections in Meteor, but it isn't for beginners. MongoDB uses $orderby operator for sorting and Meteor uses sort operator. It might not be clear how to use sort operator in Meteor from its docs.

Let's say we have a collection named Messages:

Messages = new Mongo.Collection('messages');

The schema of the collection looks like this:

{
_id: String,
  text: String,
username: String,
  timestamp: Number
}

Then we want to publish messages with limit and sort operator/option:

Meteor.publish('messages', function(limit) {
  return Messages.find({}, {
    limit: limit || 5,
    sort: { timestamp: -1 }
  });
});

sort: { timestamp: -1 } option means that we sort messages by timestamp in descendant order. If we wanted to sort messages by timestamp in ascendant order, we would use sort: { timestamp: 1 }.

Call subscribe on the client:

Meteor.subscribe('messages', 10); //subscribe 10 messages 

Write a helper that returns sorted messages. It's not enough to call Messages.find(); because it would not sort messages by timestamp:

Template.messages.helpers({
  messages: function () {
    return Messages.find({}, {
      sort: { timestamp: -1 }
    });
  }
});

Now just show messages in a template:

<template name="messages">
  {{#each messages}}
    <p>{{username}}: {{text}}</p>
  {{/each}}
</template>

That's all. I have created a chat application which you can clone and play with it: https://github.com/Elfoslav/meteor-chat-tutorial

Learn more about using MongoDB in Meteor in this video: https://www.youtube.com/watch?v=TOBex9L5Acs&index=8&list=PLoy-bs-bDKThDssbowaKGqaD_rneci8rd

 

Click to see comments


Frequently asked questions about Meteor.js 10-04-2015 (d-m-Y)

People are asking the same questions again and again. I'm tired of answering them again and again. So I decided to write this article.

Does Meteor scale?

It has already been writen on Meteorhacks. Scaling is complex stuff and I'm not expert on scaling and server stuff, but Arunoda obviously is and you should read his articles on Meteorhacks. You can read How to scale Meteor app.

Does any complex Meteor applications exist?

What is complex? Is it pexeso app or chess game? Or is it something that has thousands or even millions lines of code?

There are big production Meteor apps such as Respondly, Lookback, Kadira and a few others. Meteor is young technology and you can't expect there will be many big applications written in Meteor. I'm writing e-learning platform for learning to code (JavaScript, HTML, CSS) in Meteor and it is becoming quite complex.

Is Meteor secure?

Every application in any framework or tool is only as secure as developer makes it. You can read about Meteor security or watch video. Josh Owens has written an excellent article about Meteor security: http://joshowens.me/meteor-security-201/

How and where to deploy Meteor app?

Meteor deployment is easy because Meteor is not just a framework but it's a platform which takes care of the whole development process from creating application to deploy. If you want to just test your application, you can deploy it on Meteor's server (for free) with command "meteor deploy appname". If you want to deploy production application on your own server and domain, you will need VPS (Virtual Private Server) or cloud hosting like Heroku or Modulus. I use VPS on DigitalOcean and NPM package Meteor up.

Conclusion

There is a lot of learning resources for Meteor. There is one complex article: Learn Meteor.js Properly on JavaScript is sexy. You should read it if you want to know what exactly Meteor is.

If you have any other questions, ask in the comments.

 

Click to see comments


Joins in Meteor.js and MongoDB 08-04-2015 (d-m-Y)

One of the most asked beginner's question is: How to join collections?

Let's look at an example: We have Events collection and Users collection. Users can attend many events and events can have many visitors (users). It's M:N relationship. We can store eventId in Users collection or userId in Events collection. I chose to store userId in Events collection.

Users:

[{
_id: 1,
name: 'Bob'
},
{
_id: 2,
name: 'Josh'
}]

Events:

[{
_id: 1,
name: 'Metallica concert',
users: [ 1, 2 ]
},
{
_id: 2,
name: 'Some reggae festival',
users: [ 1 ]
}]

We can see that Bob and Josh attended Metallica concert. Bob even attended Some reggae festival. Now, how to get user's and event's data? When we define a collection, there is an option transform:

Events = new Mongo.Collection('events', {
  transform: function(doc) {
    doc.usersObj = Users.find({
      _id: { $in: doc.users }
    });
    return doc;
  }
});

Users = new Mongo.Collection('users', {
  transform: function(doc) {
    doc.eventsObj = Events.find({
      users: { $in: [ doc._id ] }
    });
    return doc;
  }
});

The transform option is a function that takes document as a parameter and we can modify it. Transform have to return the document. If we call Events.find(), Events.findOne() we will have access to usersObj property which is Users document. And Users collection will have eventsObj property.

Now, we can just call and return Events.findOne() in our helper:

Template.event.helpers({
  event: function() {
    return Events.findOne();
  }
});

Template:

<template name="event">
<h2>Event: {{event.name}}</h2>
  <h3>Users</h3>
<ul>
  {{#each event.usersObj}}
     <li>{{name}}</li>
  {{/each}}
</ul>
</template>

We iterate through event.usersObj and we can access user's properties inside this loop.

Now, how to get events for user? It's similar to how we get users for events:

Template.user.helpers({
  user: function() {
    return Users.findOne();
  }
});

Template:

<template name="user">
  <h2>User: {{user.name}}</h2>
  <h3>Events</h3>
  <ul>
    {{#each eventsObj}}
      <li>{{name}}</li>
    {{/each}}
  </ul>
</template

Thanks to transform option in collection definition is joining easy.

If you want to know how to work with joins, publications and Iron Router in real project, I have created repo that you can download and run: https://github.com/Elfoslav/meteor-join-collections

For 1:N relations you can usually store related data as sub-document. For example blogpost and comments:

[{
_id: 1,
name: 'Joins in Meteor.js and MongoDB',
comments: [{
_id: 1,
username: 'Foo',
text: 'Great article!'
}, {
_id: 2,
username: 'Bar',
text: 'Amazing!'
}]
},
{
_id: 2,
name: 'Why I love JavaScript and Meteor.js',
comments: []
}]

For more info read Reactive Joins and Official MongoDB docs.

Edit: You can also use Collection helpers package for joins.

 

Click to see comments


Array of objects as a client-side collection in Meteor 02-01-2015 (d-m-Y)

You might need to use client-side only array of objects, so you create something like this:

var persons = [
{ id: 'a1', name: 'John', age: 23 },
{ id: 'a2', name: 'Josh', age: 25 },
{ id: 'a3', name: 'Tom', age: 26 }
];

Everything is OK untill you want to search in persons array by id, name or age. You can find existing functions around the internet for this, but we have better solution in Meteor. We can use local-only Meteor Collections.

//pass null as collection name, it will create
//local only collection
Persons = new Mongo.Collection(null);
var persons = [
{ id: 'a1', name: 'John', age: 23 },
{ id: 'a2', name: 'Josh', age: 25 },
{ id: 'a3', name: 'Tom', age: 26 }
];

for (var i = 0; i < persons.length; i++) {
Persons.insert(persons[i]);
}

var tom = Persons.findOne({ name: 'Tom' });

That's all. You can just use your existing local array and insert its values into local Persons collection. This solution takes advantage of Meteor collections implementation. I love it.

Click to see comments


Meteor Day in Prague 07-11-2014 (d-m-Y)

Meteor Day meetups took place all around the world. The meaning of Worldwide Meteor Day was to celebrate release of Meteor 1.0, learn more about Meteor and meet local Meteor developers and enthusiasts.

Meteor Day in Prague took place in nice place called Impact Hub. We started with introduction to Meteor and some example apps. Then attenders installed Meteor on their computers and they could try to write simple Meteor apps.

Meteor Day Prague

Then we had hangout with Meteor core developer and other Meteor Day Meetups which took place at the same time (in our timezone).

After that anyone could do a presentation about their experience with Meteor and apps built with it.

The first presentation was from fulltime C# woman developer Vladka who builds her songbook site Agama2000 in spare time. She talked about differences between corporate C# applications and Meteor.

I did a quick presentation about my Meteor projects. My first project was TodoToday. I have built it because I didn't like any existing task manager app and I needed to measure my time. The second app I have built was Seenist. This is my biggest Meteor app and I have learned a lot while building it. I recommend everyone to build larger app. You will learn a lot. Typefast is simple app for competition in typing. Real-time of course. FasterChat is a special chat app available also for Android and FirefoxOS. You can chat with your friends faster because you can see every single letter which your friend is typing. So you can type response while your friend is typing his message. It's fun, try it!

The third presentation was from Radoslav about Taskee and site for cottages reservation in Slovakia http://huranachatu.sk/. It was nice to hear about real-time reservations. And it was even more nice to hear that he uses Meteor in his company.

I asked Radoslav after his presentation:

- So you use Meteor in your company?

- Yes. I don't have time for building applications in PHP.

I started to laugh. This sentence will remain in my memory for a long time.

I talked to a few people after presentations. Some of them told me they don't have any experience with Meteor but they want to learn it. I told them they are on the right way and they definitely should learn it. People who already built something in Meteor told me how they enjoyed working with Meteor.

Meteor Day was so great that I had to write this article right after I returned from the meetup. Especially the part of talking to people was enjoyable.

Click to see comments


Simulate longer response from server in Meteor.js 03-10-2014 (d-m-Y)

When I develop an app on localhost, everything is ok. Until I deploy it. I usually see longer responses from server and user interface seems to be frozen for a while. To simulate longer response on localhost you can use Meteor._sleepForMs():

//server
Meteor.methods({
  'yourMethod': function() {
    Meteor._sleepForMs(2000); //to simulate longer response sleep for 2 seconds
    //do something    
    return 'something';
  }
});

Don't forget to delete Meteor._sleepForMs() before deploy ;-).

Or if you often forget, you can check if the code runs on localhost:

//server
Meteor.methods({
  'yourMethod': function() {
    if (/localhost/.test(Meteor.absoluteUrl())) {
      Meteor._sleepForMs(2000); //to simulate longer response sleep for 2 seconds only on localhost
    }
    //do something    
    return 'something';
  }
});

Enjoy.

EDIT: You can use latency compensation if you don't want to wait for the server response.

Click to see comments


Just another advantage of Meteor 30-09-2014 (d-m-Y)

Another advantage of Meteor is - easy to setup a project for another developer.

I have worked on some PHP projects where I had to setup virtual host, database, bower, grunt, composer... so many things which usually take hours. This can be intimidating and frustrating for new developer. I don't want to experience it again.

In Meteor, you can just clone project repository, run meteor update and run your project with meteor run. So easy, it can do every children. Or am I wrong? Do you have frustrating experience with setup Meteor project? Let me know!

Click to see comments


Meteor methods and remote API calls 11-09-2014 (d-m-Y)

Meteor methods is nice concept but when we want to use remote API calls, there can be unexpected results.

For example, you want to show users from remote API. On the client you will do:

//client
Template.hello.helpers({
  remoteUsers: function() {
    Meteor.call('getRemoteUsers', function(err, users) {
      Session.set('remoteUsers', users);
    });
    return Session.get('remoteUsers');
  }
})

Method getRemoteUsers can look like this:

//server
Meteor.methods({
  getRemoteUsers: function() {
    Future = Npm.require('fibers/future');
    var future = new Future();

    //simulate longer response. This can be call to remote API
    setTimeout(function() {
      future.return([ 'Peter', 'John', 'Monica', 'Julia' ]);
    }, 2000);

    //wait for future.return
    return future.wait();
  }
});

So the first time remoteUsers helper is called, getRemoteUsers method is called and Session.get('remoteUsers') returns undefined. When getRemoteUsers method returns result, Session is changed and remoteUsers helper is called again. So getRemoteUsers method is also called again. And when it returns users, Session is changed with the same data as before. This causes unnecessary double API call.

We can do something like this:

Template.hello.helpers({
  remoteUsers: function() {
    //call getRemoteUsers only when remoteUsers session is falsey
    if (!Session.get('remoteUsers')) {
      Meteor.call('getRemoteUsers', function(err, users) {
        Session.set('remoteUsers', users);
      });
    }
    return Session.get('remoteUsers');
  }
});

But this is not elegant solution. Elegant solution would be not using Session at all. When Meteor.call could return result from method synchronously.

Here you can see more code: https://github.com/Elfoslav/meteor-methods

Click to see comments


Meteor run without creating local Mongo database 02-09-2014 (d-m-Y)

Meteor by default creates local mongodb database (projectname/.meteor/local/db) when you run:

$ meteor run

This local database is about 500MB large. If you have 10 Meteor projects, they can take too much disc space. Fortunately, there is a solution for this.

If you have mongodb already installed just run Meteor project with command:

$ MONGO_URL=mongodb://localhost:27017/meteorprojectname meteor run

If you don't want to type this every time you run your project you can create a bash script:

$ echo 'MONGO_URL=mongodb://localhost:27017/meteorprojectname meteor run' > run.sh

And add it run permissions: 

$ sudo chmod 777 run.sh 

So you can run it:

$ ./run.sh

Now you can delete .meteor/local/db folder in your project. Meteor will save your data in your localhost mongodb.

Click to see comments


Why I think MeteorJS will rule programming world 26-08-2014 (d-m-Y)

There are many ways and tools for building applications but in most cases you solve the same problems - JavaScript & CSS minification, CSS preprocessors compilation, SEO in JavaScript apps, deployment, backend & frontend frameworks, database settings... this all consumes so much time.

Meteor.js solves all these problems

Meteor is a fullstack JavaScript platform for building realtime applications. Fullstack means you don't have to choose frontend and backend frameworks. Meteor has its own solution for dealing with frontend and backend stuff. It's built on top of Node.js.

Meteor is not just a toy

It's a serious project backed by Andreessen Horowitz http://venturebeat.com/2012/07/25/meteor-funding/

Meteor is still not v1.0 (at the time of writing this article) but people build a lot of great apps with it:

Edit: Meteor v1.0 was released in October 2014 (one day after my birthday, nice gift!). There has been built a few cool Meteor applications since this article was published, for example:

Easy to setup and run

Once you have Meteor installed you can create your projects with $ meteor create project-name command. It will create basic project structure. And then you just run meteor development server in the current project with $ meteor run command. And you can start developing. Without any configuration of database etc.

Isomorphic JavaScript

Isomorphic JavaScript means that you can use the same piece of code on the client and on the server. Meteor takes this advantage.

Meteor and mobile

We can look forward to Meteor Cordova support.

Meteor's community

Meteor's community is the best community in the universe. All the people are fascinated by Meteor. They help each other and they create amazing things. Be the part of this community and you will see...

Rapid development

With Meteor you can build your prototypes and thereafter fully working secure (if you know how :)) applications very fast. Meteor's homepage says "Meteor is an open-source platform for building top-quality web apps in a fraction of the time, whether you're an expert developer or just getting started." And it's true.

What are you waiting for?

You should try Meteor right away. Go to https://www.meteor.com/ and enjoy better way to build apps.

Meteor resources

The end

Meteor has more features than I mentioned in this article. To keep this article short I won't mention them here. You have to discover them by yourself.

Once you master Meteor, you will not want to use anything else.

 

Click to see comments


Login with Facebook, Twitter and Google in Meteor 20-11-2013 (d-m-Y)

appId, consumerKey and clientId are quite inconsistent and confusing for new programmers. I have tried to use appId in every service, but it worked just for Facebook. Twitter needs consumerKey and Google needs clientId.

Create your Facebook app, disable sandbox mode and set site url with login:

fbauth

Create your Twitter app and follow this settings:

twitter app settings

twitter app settings

For authentication we need Read only access. The Callback URL must be the same as on image (http://127.0.0.1:3000/_oauth/twitter?close). Twitter doesn't support address http://localhost so it must be localhost's IP. Organization name and website can be empty.

Switch to tab "OAuth tool", so you can see consumer key and secret:

twitter app oauth

twitter oauth

Twitter is done.

Create your Google project and register your app:

Choose "Web Application":

google app

And setup Oauth:

Web origin: http://localhost:3000/
Redirect URI: http://localhost:3000/_oauth/google?close

So now you have:
Facebook: appId, secret
Twitter: consumerKey, secret
Google: clientId, secret

And we can put it into Meteor server (/server/accounts.js for example):

// first, remove configuration entry in case service is already configured
Accounts.loginServiceConfiguration.remove({
  service: "facebook"
});
Accounts.loginServiceConfiguration.insert({
  service: "facebook",
  appId: "yourAppId",
  secret: "yourSecret"
});

// first, remove configuration entry in case service is already configured
Accounts.loginServiceConfiguration.remove({
  service: "twitter"
});
Accounts.loginServiceConfiguration.insert({
  service: "twitter",
  consumerKey: "yourConsumerKey",
  secret: "yourSecret"
});

// first, remove configuration entry in case service is already configured
Accounts.loginServiceConfiguration.remove({
  service: "google"
});
Accounts.loginServiceConfiguration.insert({
  service: "google",
  clientId: "yourClientId",
  secret: "yourSecret"
});


And thats' it. I hope it's clearer than it was to me.

Now you can call Meteor.loginWithFacebook(), Meteor.loginWithTwitter() or Meteor.loginWithGoogle().

Or just use accounts-ui package. If you want to customize you Accounts UI look at http://blog.benmcmahen.com/post/41741539120/building-a-customized-accounts-ui-for-meteor

http://blog.benmcmahen.com/post/41741539120/building-a-customized-accounts-ui-for-meteor

Click to see comments


Why I love JavaScript and Meteor.js 02-11-2013 (d-m-Y)

Context switching

You all know it. You are coding in PHP for a long time, then you need to write something in JavaScript and you are lost. You remember PHP functions, but you have to Google JS functions because you don't remember them. When I coded something in JavaScript, then switched to PHP, I tried to concatenate strings like in JavaScript:

$a += 'b';

instead of

$a .= 'b';

When you write in one universal language, development speed is increased because you focus on one language and you don't have to learn another. And you bet JavaScript is universal language. You can write Windows 8 apps, mobile apps (Phonegap/Cordova), server side apps (NodeJS) and even operating systems (http://nodeos.github.io/).

There are lots of great JavaScript frameworks. Client side: Angular, Backbone, Ember,... and server side: Express, Sails, Geddy, Meteor... and many more. When I just took a quick look at the frameworks I fell in love with Meteor. It was love at first sight. My first Meteor project is http://todotoday.meteor.com and it's quite fast. And realtime.

What Meteor has other frameworks have not?

  • Realtime app from scratch (it's overkill feature)
  • Simple deployment (simplest and fastest i'v ever seen)
  • Live programming - you dont have to refresh page when you want to see your changes. When you change and save file in Meteor project, Meteor will automatically refresh the page.
  • flexible application structure http://docs.meteor.com/#structuringyourapp. This may be confusing for beginners. When I started with Meteor, it took me some time to find the right app structure for me. I will cover this topic in upcoming article.

Other Meteor features:

  • command line - create project with "meteor create projectname", add/remove packages, start meteor server...
  • package management - "meteor add less" will add less package into your project and you can instantly use less instead of css files. Meteor has some built in packages http://docs.meteor.com/#packages and there is community package server https://atmosphere.meteor.com/

Future of Meteor

Recently has been introduced Meteor Marketplace idea http://meteorhacks.com/the-meteor-marketplace.html. As Jidefr mentioned in his comment, implementing this idea could harm current opensource packages idea. Now you can publish your packages for free and help other developers. But if you could sell your package wouldn't you do that? In other hand, paid packages can be copmlex solutions (like forum, chat,...) provided in high quality and customizability.

Meteor has a roadmap on Trello https://trello.com/b/hjBDflxp/meteor-roadmap so you can see what's going to be implemented. Meteor popularity and community is growing every day. Packages count and quality on Atmosphere also grow.

Conclusion

Meteor is still young but powerfull tool. Many people think that Meteor is not ready for production yet (Meteor is not even v1.0. At the time of writing this article it has v0.6.6.2), but I think it is ready. And I will prove it in my next application. Look at NodeJS. Does it have 1.0 version? No. But there are many frameworks, tools and other stuffs built on top of Node. So try Meteor, fall in love with it and build great things.

Click to see comments