Skip to content

Instantly share code, notes, and snippets.

@surfjedi
Forked from bajtos/0-desc.md
Last active August 29, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save surfjedi/f410cc336423a51f2295 to your computer and use it in GitHub Desktop.
Save surfjedi/f410cc336423a51f2295 to your computer and use it in GitHub Desktop.

Imagine a chat server persisting the messages, a simplified Slack chat. The domain is designed in the object-orientated style. In order to get realtime updates, we need to transport events emitted on the model constructor ("static" events) and on a model instance ("instance" events).

While it may not be immediately clear, the example is covering few other important LoopBack concepts too:

  • authorization (loopback.token in REST)
  • current context (loopback.context in REST)

What is not covered:

  • file uploads and downloads
// will be done via common/models/chat-room.{js,json}
var ChatRoom = loopback.createModel('ChatRoom', { name: 'string' });
ChatRoom.prototype.join = function(cb) {
var user = loopback.getCurrentContext().get('currentUser');
this.users.link(user, function(err) {
if (err) return cb(err);
this.emit('joined', user); // converted to JSON by strong-remoting
cb();
});
};
ChatRoom.remoteMethod('join', { /*...*/ });
ChatRoom.prototype.post = function(message, cb) {
var user = loopback.getCurrentContext().get('currentUser');
this.posts.create(
{
author: user.id,
message: message
},
function(err, post) {
if (err) return cb(err);
this.emit('posted', post); // converted to JSON by strong-remoting
cb();
});
}
ChatRoom.remoteMethod('post', { /*...*/ });
/** server/server.js **/
var app = loopback();
app.dataSource('db', { connector: 'memory' });
app.model(ChatRoom, { dataSource: 'db' });
app.setupWebsocketTransport(); // TODO
app.listen();
// model is defined using the browserified client
var ChatRoom = app.models.ChatRoom;
var User = app.models.User;
function login(username, password, cb) {
User.login(
{ username: username, password: password},
function(err, token) {
if (err) return cb(err);
ChatRoom.find(function(err, allRooms) {
if (err) return cb(err);
// TODO: GUI - render list of rooms
ChatRoom.on('changed', function(room) {
// TODO: GUI - add a new room to the list
});
ChatRoom.on('deleted', function(roomId) {
// TODO: GUI - remove the room from a list
});
cb();
});
});
}
function join(room, cb) {
room.join(function(err) {
if (err) return cb(err);
async.parallel([
function fetchPosts(next) {
room.posts(function(err, posts) {
if (err) return next(err);
// TODO: GUI - render a list of existing posts
room.on('posted', function(post) {
// TODO: GUI - add the new post to the chat window
});
next();
});
},
function fetchUsers(next) {
room.users(function(err, users) {
if (err) return next(err);
// TODO: GUI - render a list of users
room.on('joined', function(user) {
// TODO: add user to the list of connected users
});
next();
});
},
], cb);
};
}
function post(room, message, cb) {
room.post(message, function(err, msg) {
if (err) return cb(err);
// TODO: GUI - add the new post to the chat window
cb();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment