0

I am having trouble displaying the items a user has bookmarked.

The code to get the bookmarks is as follows:

app.factory('API', function($firebaseArray, $firebaseObject, FBURL, $q) {
  var ref = new Firebase(FBURL);

  /* 
  Called to retrieve the list of items bookmarked
  */

  API.getBookmarks = function(userID) {
    var defer = $q.defer();
    var query = ref.child('Users').child(userID).child('bookmarkedItems');
    $firebaseArray(query).$loaded(function(data) {
      var bookmarks, i, itemKey;
      i = 0;
      bookmarks = {};
      while (i < data.length) {
        itemId = data[i].$id;
        bookmarks[itemKey] = API.getSingle(itemId);
        i++;
      }
      defer.resolve(bookmarks);
    });
    return defer.promise;
  };

  /* 
  Called to retrieve the items in the bookmark list 
  */

  API.getSingle = function(itemId) {
    var defer = $q.defer();
    var query = ref.child('Items').child(itemId);
    $firebaseObject(query).$loaded(function(data) {
      defer.resolve(data);
    });
    return defer.promise;
  };
  return API;
});

The trouble is that API.getBookmarks('someUserId') is returning me a list of promises attached to each item.$id instead of the items' data. So, the problem arises from my use of asycnhronous functions, but it appears that I am using defer and $loaded in the proper places to deal with these issues.

Does anyone have an idea of how to fix it?

Also, not entirely relevant, but I want to note that this operation worked perfectly fine before I just updated from AngularFire 0.9x to 1.1.1, and the changelog notes some issues with the firebaseArray $loaded function resolving before it should.

AJeezy9
  • 1,159
  • 2
  • 11
  • 15
  • From reading the code it indeed seems like `getBookmarks` will return a list of promises. That's a fact, not a problem. What *is* the problem? – Frank van Puffelen May 25 '15 at 00:04
  • If you are trying to return the actual data, that's not possible since it has not been loaded yet. You cannot make an asynchronous operation synchronous in JavaScript. For ways to deal with this, read http://stackoverflow.com/questions/27049342/asynchronous-access-to-an-array-in-firebase/27050749#27050749. – Frank van Puffelen May 25 '15 at 00:07
  • @FrankvanPuffelen: Thanks for your help, but where is the unresolved promise though? The getSingle function resolves perfectly fine & promise-free outside of this operation. Also, not entirely relevant, but I want to note that this operation worked perfectly fine before I just updated from AngularFire 0.9x to 1.1.1, and the changelog (www.firebase.com/docs/web/libraries/angular/changelog.html) notes some issues with the firebaseArray $loaded function resolving before it should. – AJeezy9 May 25 '15 at 00:12
  • Information like that should probably be in the question, not in a comment after it. Aside from that, I'll leave this to someone who understands AngularFire better than me. – Frank van Puffelen May 25 '15 at 00:19
  • possible duplicate of [Joining data between paths based on id using AngularFire](http://stackoverflow.com/questions/30299972/joining-data-between-paths-based-on-id-using-angularfire) – Kato May 25 '15 at 18:18

1 Answers1

0

Just looking at this code it would not of worked beforehand either, as your getSingle function is returning a promise regardless of the version number. If you don't want promises to be returned... you'll have to handle that:

API.getBookmarks = function(userID) {
    var defer = $q.defer();
    var query = ref.child('Users').child(userID).child('bookmarkedItems');
    $firebaseArray(query).$loaded(function(data) {
        var bookmarks, i, itemKey;
        i = 0;
        bookmarks = {};
        while (i < data.length) {
            (function(itemId){
                API.getSingle(itemId)
                    .then(function(data){
                        bookmarks[itemKey] = data;
                    });
            })(data[i].$id);
            i++;
            /*itemId = data[i].$id;
            bookmarks[itemKey] = API.getSingle(itemId);
            i++;*/
        }
        defer.resolve(bookmarks);
    });
    return defer.promise;
};

Sidenote: your bookmarks object only has one key in it, since you never seem to update itemKey

Mathew Berg
  • 28,625
  • 11
  • 69
  • 90