-1

I have an application where i have some dropdowns that are used to filter data. Once i moved the json to firebase, i am unable to retrieve data in these dropdowns. app

The foll is the console error:

TypeError: Cannot read property 'tags' of undefined
at classifieds.ctr.js:135
at Object.forEach (angular.js:321)
at getTags (classifieds.ctr.js:134)
at classifieds.ctr.js:20
at processQueue (angular.js:15552)
at angular.js:15568
at Scope.$eval (angular.js:16820)
at Scope.$digest (angular.js:16636)
at angular.js:16859
at completeOutstandingRequest (angular.js:5804)

The foll is the code:

angular
.module("ngClassifieds") 
.controller("classifiedsCtrl", function($scope, $state, $http, classifiedsFactory, $mdSidenav, $mdToast, $mdDialog) { 


    $scope.classifieds = classifiedsFactory.ref;
    $scope.classifieds.$loaded().then(function(classifieds) {
        $scope.tags = getTags(classifieds); // call the getTags method below
        $scope.books = getBooks(classifieds); // call the getBooks method below
        $scope.authors = getAuthors(classifieds); // call the getAuthors method below
        $scope.order = ""; //for sorting in asc or desc order
    });

The foll is the getTags method:

function getTags(classifieds) {

        var tags = [];
        angular.forEach(classifieds, function(item) {
            angular.forEach(item.meta.tags, function(tag) {

                tags.push(tag);
            });

        });

        return _.uniq(tags);

    }

The foll is the error in firefox: unreachable code after return statement

Error: item.meta is undefined
getTags/<@http://localhost:8080/components/classifieds/classifieds.ctr.js:135:5
forEach@http://localhost:8080/node_modules/angular/angular.js:321:11
getTags@http://localhost:8080/components/classifieds/classifieds.ctr.js:134:4
@http://localhost:8080/components/classifieds/classifieds.ctr.js:20:18
processQueue@http://localhost:8080/node_modules/angular/angular.js:15552:28
scheduleProcessQueue/<@http://localhost:8080/node_modules/angular/angular.js:15568:27
$RootScopeProvider/this.$get</Scope.prototype.$eval@http://localhost:8080/node_modules/angular/angular.js:16820:16
$RootScopeProvider/this.$get</Scope.prototype.$digest@http://localhost:8080/node_modules/angular/angular.js:16636:15
$RootScopeProvider/this.$get</Scope.prototype.$evalAsync/<@http://localhost:8080/node_modules/angular/angular.js:16859:15
completeOutstandingRequest@http://localhost:8080/node_modules/angular/angular.js:5804:7
Browser/self.defer/timeoutId<@http://localhost:8080/node_modules/angular/angular.js:6081:7

Id really appreciate if you can help me figure where im goin wrong here. Thanks

Nosail
  • 465
  • 2
  • 7
  • 19
  • See [joining user records using a cache](https://gist.github.com/katowulf/f78d4a224c06a643ddfa) and [filtering records using $extend](https://gist.github.com/katowulf/bee266e31aa60cb0eed6) – Kato Mar 16 '16 at 15:14

1 Answers1

1

The AngularFire $loaded() event is for a very limited set of specific use-cases, where you want to handle the initially loaded data differently from other data. That is not the case here, so you should not be using $loaded().

If you have a list of tags in your database that you want to display in your view, you should get that list of tags into a $firebaseArray():

var tagsRef = ref.child('tags');
$scope.tags = $firebaseArray(tagsRef);

This will load the tags and will automatically update the view after they're loaded. Even better, it will also monitor the database for changes and update the view whenever the data is changed.

Do the same for $scope.books and $scope.authors and you'll have an easier time. It may feel counter-intuitive to set up three $firebaseArray() objects, instead of a single $firebaseObject(). But the cost is pretty much the same either way.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Frank, but how do i call the getTags() method if i were to implement this suggestion? coz tags here refers to a newly defined array that stores only one instance of all the tags against the 'tags' property on each object/word in json. – Nosail Mar 15 '16 at 13:55
  • Ah, so you're trying to filter the data. That is also possible and still not a good use-case for `$loaded()`. You'll need to extend the `$firebaseArray()` class. Probably something like in this answer by Kato (the main author of AngularFire): http://stackoverflow.com/questions/32359624/joining-angularfire-paths-on-a-value-key-is-not-working-merging-user-profiles-i – Frank van Puffelen Mar 15 '16 at 14:11
  • thanks Frank, i wasnt able to follow thru all the sugestion in the post you referenced, but this is how i implemented it, and all the data is comin thru fine now. `function getTags(classifieds) { var tags = []; angular.forEach(classifieds, function(item) { if (item.meta) { angular.forEach(item.meta.tags, function(tag) { tags.push(tag); }); } }); return _.uniq(tags); }` – Nosail Mar 16 '16 at 08:30