Fetching item by unique firebase id in angularfire 1.0.0

你。 提交于 2019-12-05 20:41:50

I know that the documentation of the $getRecord() function is kind of misleading. What you actually get from $firebaseArray is a promise of an array. It means that your posts variable will contain your posts at some point in the future. That being said, it seems that the $getRecord function only works when the promise have been resolved, i.e. when the array has been downloaded from Firebase. To make sure that the promise is resolved when you call the $getRecord function, you can use $loaded() on the promise :

var posts = $firebaseArray(ref);
posts.$loaded().then(function(x) {
    var post = x.$getRecord(postId);
    console.log(post);
}).catch(function(error) {
    console.log("Error:", error);
});

If you are wondering why it works for ng-repeat, it's because Angular knows that the posts variable is a promise and waits for it to be resolved before rendering the values.

This is happening due to promises.

  • Along the lines of what Kato, Jean-Philippe said, $firebaseArray is not immediately available as it needs to be downloaded.
  • See the .$loaded() documentation:

    .$loaded() "returns a promise which is resolved when the initial array data has been downloaded from Firebase. The promise resolves to the $firebaseArray itself."

That answers your question, and I just wanted to show another way of doing it:

  • This is a great use case for extending AngularFire services.
    • As the AngularFire API Documentation says:

      "There are several powerful techniques for transforming the data downloaded and saved by $firebaseArray and $firebaseObject. These techniques should only be attempted by advanced Angular users who know their way around the code."

  • Putting all that together, you accomplish what you want to do by:

Example

  • Here is a working JSFIDDLE example I put together that is tied to one of my public Firebase instances.
  • It's important to note that you should add ".indexOn":"timestamp" to your rules for /posts.

Factories

app.factory('PostsArray', function (FBURL, PostsArrayFactory) {
    return function (limitToLast) {
        if (!limitToLast) {
            console.error("Need limitToLast");
            return null;
        }
        var postsRef = new Firebase(FBURL + '/posts').orderByChild('timestamp').limitToLast(limitToLast);
        return new PostsArrayFactory(postsRef);
    }
});


app.factory('PostsArrayFactory', function ($q, $firebaseArray) {
    return $firebaseArray.$extend({
        getPost: function (postKey) {
            var deferred = $q.defer();
            var post = this.$getRecord(postKey);
            if (post) {
                console.log("Got post", post);
                deferred.resolve(post);
            } else {
                deferred.reject("Post with key:" + postKey + " not found.");
            }
            return deferred.promise;
        },
        createPost: function (post) {
            var deferred = $q.defer();
            post.timestamp = Firebase.ServerValue.TIMESTAMP;
            this.$add(post).then(function (ref) {
                var id = ref.key();
                console.log("added post with id", id, "post:", post);
                deferred.resolve(ref);
            }).
            catch (function (error) {
                deferred.reject(error);
            });
            return deferred.promise;
        }
    });
});

Controller

app.controller("SampleController", function ($scope, PostsArray) {

    var posts = new PostsArray(5);
    $scope.posts = posts;

    $scope.newPost = {};
    $scope.createNewPost = function () {
        posts.createPost($scope.newPost);
    }

    $scope.postId = '';
    $scope.getPost = function () {
        posts.getPost($scope.postId).then(function (post) {
            $scope.gotPost = post;
        }).
        catch (function (error) {
            $scope.gotPost = error;
        });
    }
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!