I created a Reddit clone using AngularJS and Firebase. I am working on allowing posting comments to comments (a comment thread). Firebase does not like using nested arrays, it prefers a flatten structure. I found this example of using Firebase to create nested comments, but it uses jQuery and I am really unclear how to 'translate'.
How would I go about creating "nested" (threaded) comments without actually using nested arrays?
This is my comment controller (called PostViewCtrl):
'use strict';
app.controller('PostViewCtrl', function ($scope, $routeParams, Post, Auth) {
$scope.user = Auth.user;
$scope.signedIn = Auth.signedIn;
$scope.post = Post.get($routeParams.postId);
$scope.comments = Post.comments($routeParams.postId);
$scope.addComment = function () {
if(!$scope.commentText || $scope.commentText === '') {
return;
}
var comment = {
text: $scope.commentText,
creator: $scope.user.profile.username,
creatorUID: $scope.user.uid
};
$scope.comments.$add(comment);
$scope.commentText = '';
};
$scope.deleteComment = function (comment) {
$scope.comments.$remove(comment);
};
});
And this is my Post service (to communicate with Firebase):
'use strict';
app.factory('Post', function ($firebase, FIREBASE_URL) {
var ref = new Firebase(FIREBASE_URL);
var posts = $firebase(ref.child('posts')).$asArray();
var Post = {
all: posts,
create: function (post) {
return posts.$add(post).then(function(postRef) {
$firebase(ref.child('user_posts').child(post.creatorUID))
.$push(postRef.name());
return postRef;
});
},
get: function (postId) {
return $firebase(ref.child('posts').child(postId)).$asObject();
},
delete: function (post) {
return posts.$remove(post);
},
comments: function (postId) {
return $firebase(ref.child('comments').child(postId)).$asArray();
}
};
return Post;
});
Both the DOM and a comment thread are tree data structures. HTML is built to support trees, but it is a common problem to store them in databases. One solution to this problem is to using an adjacency list.
In this list, each resource, or in this case comment, would store a parent_id that is identical to the id of the comment it is nested under—creating a "flat" data structure.
It is important to acknowledge that Firebase uses Mongo, which is a hierarchical database, so it is possible to "nest" data; however, this is advised against by the creators, so let's stick with the "flat" approach.
Given we now have a "flat" data structure, we still need to convert it into a nested data structure so it can render nicely to the DOM. Here's an example of how to build a tree from a flat data structure in JavaScript and here's a library to the same effect.
Finally, once you have your nested comments, or a comment thread, I'd recommend following this blog post on building a nested, recursive directive in angular to render it to the DOM.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With