Search code examples
javascriptangularjsundefined-function

Undefined is not a function & dependency injection


New to AngularJs I'm trying to train by building a single page Todo Application. The problem is, I'm having trouble loading a localStorage factory I'm trying to use for this. At the moment i'm stuck on the following error :

Undefined is not a function at routeconfig.resolve.store on app.js line 11.

Here's the code :

app.js

angular.module('TodoAngular', ['ngRoute'])
    .config(function($routeProvider) {
    'use strict';

    var routeConfig = {
        controller: 'TodoController' ,
        templareUrl: 'app/partials/TodoList.html',
        resolve: {
          store: function (todoAngularStorage) {
              // Récupère le module qui gère le localStorage
              return todoAngularStorage.then(function (module) {
                  module.get(); // Récupère les données
                  return module;
              });
          }
        }
    };

    $routeProvider
        .when('/todos', routeConfig)
        .otherwise({ 
            redirectTo: '/todos' 
        });
    }     
);

todoAngularStorage.js

angular.module('TodoAngular')
    .factory('todoAngularStorage', function ($http,$injector) {
        'use strict';

       return $injector.get('localStorage');
    })

    .factory('localStorage', function($q) {
        'use strict';

        var STORAGE_ID = 'todoAngularLocalStorage';

        var store = {
            todos: [],

            //récupérer depuis le local storage
            _getFromLocalStorage: function(){
                return JSON.parse(localStorage.getItem(STORAGE_ID) || '[]');
            },

            //enregistrer dans le local storage
            _saveToLocalStorage: function (todos) {
                localstorage.setItem(STORAGE_ID, JSON.stringify(todos));
            },

            //supprimer un Todo
            delete: function (todo) {
                //instanciation de l'API Deferred
                var deferred = $q.defer();

                store.todos.splice(store.todos.indexOf(todo), 1);

                store._saveToLocalStorage(store.todos);
                deferred.resolve(store.todos);

                return deferred.promise;
            },

            //récupérer les todos
            get: function () {

                //instanciation de l'API Deferred
                var deferred = $q.defer();

                angular.copy(store._getFromLocalStorage(), store.todos);
                deferred.resolve(store.todos);

                return deferred.promise;

            },

            //ajouter un todo à la fin de la todo list  
            insert: function (todo) {

                //instanciation de l'API Deferred
                var deferred = $q.defer();

                store.todos.push(todo);

                store._saveToLocalStorage(store.todos);
                deferred.resolve(store.todos);

                return deferred.promise;

            }
      };

      return store;
});

I've been trying to debug it and it appears that the problem comes from the 'module' passed in the function in the following line of my app.js file

return todoAngularStorage.then(function (module) {

I've been following this example (https://github.com/tastejs/todomvc/tree/master/examples/angularjs) while building my app and I really don't see where's my mistake at the moment.


Solution

  • Your localStorage service factory is returning an object that doesn't have any property called then. You're then returning the same object from todoAngularStorage factory and trying to use then property of the returned value as a function, hence your error. It looks like you just wanted to do this:

    return todoAngularStorage.get().then(function () {
        return todoAngularStorage;
    });
    

    As a sidenote, you should be able to find this out by debugging (setting a breakpoint at the place where the problem is and looking at the variable values) and looking at your code (where did that value come from).