Normalized records in angularFire

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/1.0.11/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/0.7.1/angularfire.min.js"></script>
<h3>Normalizing user profiles into posts</h3>

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

JavaScript

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

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

app.factory('userCache', function ($firebase) {
    return function (ref) {
        var cachedUsers = {};
        cachedUsers.$load = function (id) {
            if( !cachedUsers.hasOwnProperty(id) ) {
                cachedUsers[id] = $firebase(ref.child(id));
            }
            return cachedUsers[id];
        };
        cachedUsers.$dispose = function () {
            angular.forEach(cachedUsers, function (user) {
                user.$off();
            });
        };
        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,
            dateCreated: 1397584465
        }
    },
    users: {
        "simplelogin:1": {
            email: "[email protected]",
            name: "Jake Smith",
            jobTitle: "Supreme Master of the Universe"
        },
        "simplelogin:2": {
            email: "[email protected]",
            name: "Michael 'Kato' Wulf",
            jobTitle: "Awesome Dude"
        }
    }
});