Search code examples
javascriptangularjsangularjs-factory

AngularJS functions from factory service not responding (proper injection?)


I'm a student learning AngularJS and i can't seem to figure out why the functions from factory service is not responding in my view. I think i'm calling the functions incorrectly but I've tried calling it so many ways that i'm not sure what is going on anymore. Also, there's no error in console so i'm not sure what is happening. Appreciate any help and thanks for your time!

So I have my factory todoService.js here:

(function() {
    function TodoFact($firebaseArray) {
        var TodoFact = {};

        var todos = $firebaseArray(firebase.database().ref().child('/todo'));

        TodoFact.addTodo = function(){
            todos.$add(todo);
            todo.complete = false;
        };

        TodoFact.removeTodo = function(todo) { 
            var index = $scope.todos.indexOf(todo);
            $scope.todos.$remove(todo);
        };

        TodoFact.complete = function(todo) {
            todo.complete = true;
            todos.$save(todo);
        };

        var addFormShow = false;

        TodoFact.toggleForm = function() {
            addFormShow = addFormShow === false ? true : false;
        };

        return TodoFact;
    };

    angular
        .module('markOff')
        .factory('TodoFact', ['$firebaseArray', TodoFact]);   
})();

It is being injected into the Controller TodoCtrl.js here

(function() {
    function TodoCtrl(TodoFact) {
        this.todoFact = TodoFact;
    }
        angular
            .module('markOff')
            .controller('TodoCtrl', ['TodoFact', TodoCtrl]);
})();

I'm using ui-router and the routing has no issue. I've also added scripts for todoService.js and controllers appropriately.

<script src="/scripts/app.js"></script>

<script src="/scripts/controllers/TodoCtrl.js"></script>

<script src="/scripts/services/todoService.js"></script>

Here is a part of the view that i'm trying to solve. Basically, on click event the element will toggle show / hide.

<div class="pull-right">
      <!-- Calling ToggleForm on click event, the element will show when addFormShow is false-->
      <a class="btn btn-success" ng-click="todoFact.toggleForm()" ng-show="!todoFact.addFormShow"><span class="ion-loop"></span>Add</a>

      <!-- Calling ToggleForm on click event, ng-show if addFormShow is true -->
      <a class="btn btn-success" ng-click="todoFact.toggleForm()" ng-show="todoFact.addFormShow"><span class="ion-loop"></span>Cancel</a>
</div>

* edit *

This is how i'm routing to the view with controllers

(function() {
    function config($stateProvider, $locationProvider) {
        $locationProvider
            .html5Mode({
                enabled: true,
                requireBase: false
            });
        $stateProvider
            .state('todo', {
                url: '/todo',
                controller: 'TodoCtrl as todo',
                templateUrl: '/templates/todo.html'
            });
    angular
        .module('markOff', ['firebase', 'ui.router'])
        .config(config);
})();

Solution

  • Since the router uses "controllerAs" syntax:

       $stateProvider
            .state('todo', {
                url: '/todo',
                controller: 'TodoCtrl as todo',
                templateUrl: '/templates/todo.html'
            });
    

    The template needs to prepend todo to the variables:

    <div class="pull-right">
          <!-- Calling ToggleForm on click event, 
               the element will show when addFormShow is false-->
          <a ng-click="todo.todoFact.toggleForm()" 
             ng-show="!todo.todoFact.addFormShow">Add</a>
    
          <!-- Calling ToggleForm on click event, ng-show if addFormShow is true -->
          <a ng-click="todo.todoFact.toggleForm()" 
             ng-show="todo.todoFact.addFormShow">Cancel</a>
    </div>
    

    Also in the TodoFact factory, the addFormShow variable needs to be a public property of the TodoFact object.

        //var addFormShow = false;
        TodoFact.addFormShow = false;
    
        TodoFact.toggleForm = function() {
            //addFormShow = addFormShow === false ? true : false;
            TodoFact.addFormShow = TodoFact.addFormShow === false ? true : false;
        };
    
        return TodoFact;