1

I have a Controller and Factory to handle lists. The controller needs to get the lists loaded by the factory and display it in the view. I can't have a getLists() method in the factory because this needs to load asynchronously from FireBase. Here is my controller code-

angular.module('myApp.controllers', []).
  controller('ListCtrl', ["$scope","listFactory", function($scope, ListFactory) {
    $scope.lists = [];

    $scope.$on("list_update", function(snapshot)
    {
        console.log(snapshot);
    });

  }]).
  controller("EditListCtrl", ["$scope","listFactory", function($scope, ListFactory)
    {
        $scope.name = "";
        $scope.items = [];
        $scope.itemCount = 10;

        $scope.save = function()
        {
            var List = {"items":[]};
            for(var i = 0; i < $scope.itemCount; i++)
            {
                var item = $scope.items[i];
                if(item != null)
                {
                    List.items.push(item);
                }
                else
                {
                    alert("Please fill all items of the list.");
                    return false;
                }

                ListFactory.putList(List);
                $scope.items = [];
                $scope.name = "";
            }
        }
    }]);

The listFactory looks like this-

angular.module("myApp.factories", [])
    .factory("listFactory", [function()
    {
        var lists = [{"name":"test"}];
        var ListRef = new Firebase("https://listapp.firebaseio.com/");

        var factory = {};
        factory.getLists = function()
        {
            // this won't work
        }

        factory.putList = function(List)
        {
            ListRef.child("lists").push(List);
        }

        ListRef.on("child_added", function(snapshot)
        {
            // How do I get this back to the controller???
        });

        return factory;
    }]);

The ListRef will dispatch a "child_added" event where the snapshot argument is has the list data. I need to get this back to the controller somehow. I'd like to do this with events but I'm not sure how to do that between the factory and the controller. I don't want to use the root scope because I think that's bad practice.

I'm new to this- any help would be appreciated!

1 Answer 1

1

Firstly update your list variable to have a container object:

var lists = { items: [{ name: 'test' }] };

Then expose access to the list through the factory, eg:

factory.getLists = function() {
    return lists;
}

Then set a scope var in your controller:

$scope.lists = ListFactory.getLists();

Then whenever the child_added event is triggered, update the lists.items, and the $scope from the controller should reflect the changes.

Sign up to request clarification or add additional context in comments.

5 Comments

Ok well it does sort of work but only if I start manipulating the view. When the page loads it should pull in 2 lists but it only does when I start typing in one of the input boxes. Any idea why?
Just guessing, I would say either the initial list grab isn't being run until the view changes, or the lists are grabbed, but not bound to the $scope until the view changes. Are you able to create a fiddle?
Took a while to compile from the files but here is a fiddle of it- jsfiddle.net/ZwT7g/1
The reason it isn't working on load, it because the firebase callback, while updating the correct value is operating outside of the usual scope process. Inject $rootScope into your factory, and wrap the child_added for loop with $rootScope.$apply(function(){ ... });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.