Normalized records in angularFire (for 0.9.x and above)

Uses a userCache service to normalize user names from ids in a list of messages and cache them locally as needed.

by Kato Richardson

HTML

<script src="https://cdn.firebase.com/js/client/2.2.9/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/1.1.2/angularfire.min.js"></script>
<h3>Normalizing user profiles into posts</h3>

<ul ng-controller="ctrl">
    <li ng-repeat="post in posts" ng-init="user = users.$load(post.user)">
        {{user.name}}: {{post.title}}
    </li>
</ul>

JavaScript

// for a simpler approach, see also:
// https://gist.github.com/katowulf/f78d4a224c06a643ddfa

var app = angular.module('app', ['firebase']);
var fb = new Firebase('https://katowulf-normalized-messages.firebaseio-demo.com/');

app.controller('ctrl', function ($scope, $firebaseArray, userCache) {
    $scope.posts = $firebaseArray(fb.child('posts'));
    $scope.users = userCache(fb.child('users'));
});

app.factory('userCache', function ($firebaseObject) {
    return function (ref) {
        var cachedUsers = {};
        // loads one user into the local cache, you do not need to
        // wait for this to show it in your view, Angular and Firebase
        // will work out the details in the background
        cachedUsers.$load = function (id) {
            if( !cachedUsers.hasOwnProperty(id) ) {
                cachedUsers[id] = $firebaseObject(ref.child(id));
            }
            return cachedUsers[id];
        };
        // frees memory and stops listening on user objects
        // use this when you switch views in your SPA and no longer
        // need this list
        cachedUsers.$dispose = function () {
            angular.forEach(cachedUsers, function (user) {
                user.$destroy();
            });
        };
        // removes one user, note that the user does not have
        // to be cached locally for this to work
        cachedUsers.$remove = function(id) {
            delete cachedUsers[id];
            ref.child(id).remove();
        };
        return cachedUsers;
    }
});

// reset demo data on each page load
fb.set({
    posts: {
        "post1": {
            title: "This is a link to my favorite website!",
            url: "http://www.firebase.com",
            user: "simplelogin:1",
            upvotes: 2,
            dateCreated: 1397547310
        },
        "post2": {
            title: "Another cool website",
            url: "http://www.google.com",
            user: "simplelogin:2",
            upvotes: 1,
           ...