About: A full-stack developer with actuarial statistics background, had been building hardware & software (backend systems & web applications) for more than 15 years, especially industrial automation & suppl
Location:
Puchong, Selangor, Malaysia
Joined:
Jan 10, 2022
Creating a Minimal Reddit App with Meteor 3 and Blaze
After installation, you should see a success message confirming Meteor 3.1.2 has been installed in your home directory.
log
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 7869 0 7869 0 0 8837 0 --:--:-- --:--:-- --:--:-- 8831
Downloading Meteor distribution
######################################################################## 100.0%
Meteor 3.1.2 has been installed in your home directory (~/.meteor).
Writing a launcher script to /usr/local/bin/meteor for your convenience.
This may prompt for your password.
To get started fast:
$ meteor create ~/my_cool_app
$ cd ~/my_cool_app
$ meteor
Or see the docs at:
docs.meteor.com
Deploy and host your app with Cloud:
www.meteor.com/cloud
Next, create a new Meteor app with Blaze:
meteor create meteor-app --blaze --prototype
The --prototype flag includes the autopublish and insecure packages, which are helpful for rapid prototyping. These packages automatically publish all data to the client and allow client-side database modifications without explicit permissions. While convenient for development, they should be removed before deploying to production for security reasons.
log
Using blaze skeleton
Created a new Meteor app in 'meteor-app'.
To run your new app:
cd meteor-app
meteor --port 3001
If you are new to Meteor, try some of the learning resources here:
https://www.meteor.com/tutorials
When you’re ready to deploy and host your new Meteor application, check out Cloud:
https://www.meteor.com/cloud
Let's test our new app
cd meteor-app
meteor --port 3001
log
[[[[[ ~/meteor-pulumi-esc/meteor-app ]]]]]
=> Started proxy.
=> Started HMR server.
=> Started MongoDB.
=> Started your app.
=> App running at: http://localhost:3001/
User authentication (accounts-password, accounts-ui)
Input validation (check)
Runtime support for ES6+ features (@babel/runtime)
jQuery for DOM manipulation
Creating the Data Model
Let's set up our data structure. Create a new folder structure imports/api and add a file collections.js.
import{Mongo}from'meteor/mongo';import{Meteor}from'meteor/meteor';import{check}from'meteor/check';exportconstPosts=newMongo.Collection('posts');// Define security rules if not using autopublishif (Meteor.isServer){// PublicationsMeteor.publish('allPosts',function(){returnPosts.find({},{sort:{votes:-1,createdAt:-1}});});}// MethodsMeteor.methods({'posts.insert'(title,url){check(title,String);check(url,String);if (!this.userId){thrownewMeteor.Error('not-authorized');}constuser=Meteor.users.findOneAsync(this.userId);constusername=user&&user.username?user.username:(user&&user.profile&&user.profile.name?user.profile.name:(user&&user.emails?user.emails[0].address:this.userId));returnPosts.insertAsync({title,url,createdAt:newDate(),userId:this.userId,author:username,votes:0});},'posts.upvote'(postId){check(postId,String);if (!this.userId){thrownewMeteor.Error('not-authorized');}Posts.updateAsync(postId,{$inc:{votes:1}});},});
This file defines our Posts collection and the methods to interact with it. We've implemented two key methods:
posts.insert - Creates a new post with title, URL, and author information
posts.upvote - Increments the vote count for a specific post
main - The overall layout with header and content area
postSubmit - A form for submitting new posts (only visible to logged-in users)
postsList - Displays all posts with loading and empty states
postItem - Individual post display with voting functionality
Adding Client-Side Logic
Replace client/main.js with:
import{Template}from'meteor/templating';import{Meteor}from'meteor/meteor';import{ReactiveVar}from'meteor/reactive-var';import{Posts}from'../imports/api/collections.js';import'./main.html';// Subscribe to dataMeteor.startup(()=>{Meteor.subscribe('allPosts');});// Post list templateTemplate.postsList.helpers({posts(){returnPosts.find({},{sort:{votes:-1,createdAt:-1}});}});// Post item templateTemplate.postItem.onCreated(function(){// Use the data context's _id, not this._idthis.autorun(()=>{constdata=Template.currentData();});});Template.postItem.events({'click .upvote'(event,template){event.preventDefault();Meteor.call('posts.upvote',this._id);},});// Post submit templateTemplate.postSubmit.events({'submit .post-submit'(event,template){event.preventDefault();consttitle=event.target.title.value;consturl=event.target.url.value;Meteor.call('posts.insert',title,url,(error)=>{if (error){console.error("Error adding post:",error);}else{// Clear formevent.target.title.value='';event.target.url.value='';}});}});
This JavaScript code:
Sets up data subscriptions
Registers a date formatting helper
Implements the sorting of posts by votes and creation date
import{Meteor}from'meteor/meteor';import{Posts}from'../imports/api/collections.js';Meteor.startup(()=>{// If the Posts collection is empty, add some dataif (Posts.find().countAsync()===0){constdummyPosts=[{title:'Introducing Moopt',url:'https://moopt.com',createdAt:newDate(),author:'System',votes:0},{title:'Discover Moopt',url:'https://linkedin.com/company/moopt',createdAt:newDate(),author:'System',votes:0}];dummyPosts.forEach(post=>Posts.insertAsync(post));}});
This server code initializes our application with sample posts if the database is empty, making it easier to see how the app works right away.
User Authentication: Sign up and login functionality
Post Creation: Logged-in users can submit new posts with titles and URLs
Voting System: Users can upvote posts they like
Sorting: Posts are automatically sorted by vote count and creation date
Responsive Design: Works well on both desktop and mobile devices
Next Steps
To make this a production-ready application, consider:
Removing the autopublish and insecure packages
Adding downvoting functionality
Implementing comments on posts
Adding user profiles and post history
Implementing categories or subreddits
Adding pagination for large numbers of posts
This tutorial demonstrates the power and simplicity of Meteor for building interactive web applications. With just a few files, we've created a functional Reddit clone that handles real-time updates, user authentication, and data persistence.
This repository demonstrates how to securely deploy a Meteor 3 application to Google Cloud Run using Pulumi ESC for secret management. The application connects to a MongoDB Atlas database, with the connection string securely stored and accessed using Pulumi ESC.