noel.felix noel.felix - 12 days ago 5
AngularJS Question

Angular Controller as ES6 Class: "[ng:areq] Argument ***Controller is not a function, got undefined"

Attempting to build a basic Angular todo application w/ES6. As far as I can tell, the controller should be registering, but I continue to get the title error when routed to the associated state.

*App.js referenced in index is the Babel transpiled Webpack output

index.html

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="node_modules/angular-material/angular-material.css" />
</head>
<body ng-app="todoApp">
<script src="../dist/app.js"></script>
<div ui-view></div>
</body>
</html>


app.js

import angular from 'angular';
import uiRouter from 'angular-ui-router';
import ngStorage from 'angular-storage';
import ngMaterial from 'angular-material';
import ngAnimate from 'angular-animate';
import ngAria from 'angular-aria';

import config from './config/config'

(() => {
const ngModule = angular.module('todoApp', [uiRouter, ngStorage, ngAnimate, ngAria, ngMaterial]);
config(ngModule);
})();


config.js

import httpAuthInterceptor from './interceptors/httpAuthInterceptor';
import constants from './constants';

import login from '../login/index';
import todos from '../todos/index';
import todo from '../todos/todo/index';
import services from '../services/index';

export default ngModule => {
httpAuthInterceptor(ngModule);
services(ngModule);

ngModule.constant('CONSTANTS', constants);

ngModule.config(($stateProvider, $urlRouterProvider, $httpProvider) => {
$urlRouterProvider.otherwise('/login');

$stateProvider
.state('login', {
url: '/login',
templateUrl: 'app/login/login.html',
controller: 'loginController as vm'
})
.state('todos', {
url: '/todos',
templateUrl: 'app/todos/todos.html',
controller: 'todosController as vm'
});

$httpProvider.interceptors.push('httpAuthInterceptor');

login(ngModule);
todos(ngModule);
todo(ngModule);
});
}


login/index.js

import controller from "./login.controller";
import service from "./login.service";

export default ngModule => {
controller(ngModule);
service(ngModule);
};


login/login.controller.js

export default ngModule => {
let controllerName = 'loginController';

class loginController {
constructor(loginService) {
this.loginService = loginService;
this.username;
this.password;
}
}

ngModule.controller(controllerName, loginController);
};


More confusing to me is that the service below loads fine:

services/index.js

import session from "./session.service";

export default ngModule => {
session(ngModule);
};


services/session.service.js

export default ngModule => {
let providerName = 'sessionService';

class sessionService {
constructor(store, CONSTANTS) {
this.CONSTANTS = CONSTANTS;
this.store = store;

this.currentSessionToken;

this.init();
}

init() {
this.currentSessionToken = this.retrieveSession();
console.log(this.currentSessionToken)
}

storeSession (token) {
this.store.set(this.CONSTANTS.JWT_TOKEN_KEY, token);
this.currentSessionToken = token;
}

retrieveSession() {
return this.store.get(this.CONSTANTS.JWT_TOKEN_KEY);
}

isAuthenticated() {
let token = this.retrieveSession();
if(token) {
let tokenParams = _parseJwt(token);
return Math.round(new Date().getTime() / 1000) <= tokenParams.exp;
} else {
return false;
}
}
}

ngModule.service(providerName, sessionService);

let _parseJwt = function(token) {
let base64Data = token.split('.')[1];
let base64 = base64Data.replace('-', '+').replace('_', '/');
return JSON.parse(this.$window.atob(base64));
}.bind(sessionService);
}

Answer

Move these three calls

login(ngModule);
todos(ngModule);
todo(ngModule);

outside the config function; they don't belong in there at all.

// in config.js

export default ngModule => {
  httpAuthInterceptor(ngModule);
  services(ngModule);
  login(ngModule);
  todos(ngModule);
  todo(ngModule);

  ngModule.constant('CONSTANTS', constants);

  ngModule.config(($stateProvider, $urlRouterProvider, $httpProvider) => {
    // etc