Heroku + Rails + Angular [$injector:nomod] - javascript

I'm having a problem with an angular.js/rails application, working locally, that results in a js crash on Heroku.
To allow for local testing, I downloaded and placed all angular.js files in the vendor directory. I'm not using any gems, simply placing the angular files in the asset pipeline so that the individual controller coffeescript files can use the angular library.
This is my app.js:
angular.module('generosity', ['ngRoute', 'templates'])
.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: "users-form.html",
controller: 'UsersController'
}).
// when('/phones/:phoneId', {
// templateUrl: 'partials/phone-detail.html',
// controller: 'PhoneDetailCtrl'
// }).
otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
}])
.controller('UsersController' ['$scope', '$http', '$rootScope', function($scope, $http, $rootScope) {
var self = this;
self.username;
self.realName;
self.password;
self.availableHours; //How should this be styled?
self.currentCity;
self.currentLocation;
self.recipient; //Should probably be renamed
$scope.errCode = 0;
self.addUser = function() {
var errCode;
$http.post('users/add', {username: self.username, password: self.password}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
var errCode = data.errCode;
self.retrieveErrCode(errCode);
// console.log("HYA" + self.errCode);
if(errCode == -2) {
alert("Error: This username already exists.");
}
else if(errCode == -3) {
alert("Error: The username is empty, too long, or has invalid characters.");
}
else if(errCode == -4) {
alert("Error: The password is empty, too long, or has invalid characters.");
}
else {
alert("User created.");
}
console.log(errCode);
$rootScope.errCode = data.errCode;
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
alert("Error.");
});
console.log(self.username);
return $scope.errCode;
}
self.retrieveErrCode = function(code) {
$scope.err = code;
console.log("here");
};
self.createDummyUser = function() {
self.username = "LordChristopher";
self.realName = "Lord Christopher";
self.password = "Team 61C";
self.availableHours = "6 to 11 pm";
self.currentCity = "Berkeley";
self.currentLocation = "Nowhere";
self.recipient = "He whose name shall not be spoken";
};
// self.login = function(name, pw) {
// };
// self.logout = function() {
// };
}])
.controller('SessionController', ['$scope', '$http', '$rootScope', function($scope, $http, $rootScope) {
var self = this;
self.userId;
self.username;
self.login = function(username, password) {
$http.post('login', {username: username, password: password}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
alert("Connected");
console.log("connected");
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log("error");
alert("Error.");
});
}
}])
.directive('navbar', function() {
return {
restrict: 'E',
templateUrl: "navbar.html"
};
})
.directive('usersForm', function() {
return {
restrict: 'E',
scope: {
},
templateUrl: "users-form.html"
};
})
.directive('loginForm', function() {
return {
restrict: 'E',
scope: {
},
templateUrl: "login-form.html"
};
})
.directive('usersTests', function() {
return {
restrict: 'E',
scope: {
},
templateUrl: "users-tests.html"
};
})
// .directive('directiveA', function() {
// return {
// restrict: 'A',
// scope: {
// name: '#',
// hobby: '#'
// },
// templateUrl: "example-module.html"
// };
// }) //Only put a semi-colon on the last directory of the module
.directive('css1', function() {
return {
restrict: 'C',
link: function(scope, element, attrs) {
element.css("width", 400),
element.css("font-style", "oblique");
element.css("color", "green");
element.css("font-size", "30px");
}
};
})
.directive('testStatus', function() { //You do not need to account for the cases for which the rating is not a number.
return {
restrict: 'C',
scope: {
message: '#'
},
link: function(scope, element, attrs) { //Note that this is a function of scope, NOT $scope!!
if(scope.message.search("PASS") > 0) {
element.css("color", "green");
}
else if(scope.message.search("FAIL") > 0) {
element.css("color", "red");
}
else {
element.css("color", "blue");
}
}
};
})
It runs just fine locally, using Rails s. However, despite my best efforts (all the "serve static assets:true" in config/assets/production.rb, and several add-on gems that auto-minify js files for production) heroku returns the following stacktrace:
Uncaught Error: [$injector:modulerr] Failed to instantiate module generosity due to:
Error: [$injector:nomod] Module 'generosity' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.3.0/$injector/nomod?p0=generosity
at https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:5:20793
at https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:5:28971
at e (https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:5:28543)
at https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:5:28855
at https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:6:4062
at o (https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:5:21178)
at h (https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:6:3840)
at _e (https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:6:5485)
at Q.s (https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:5:26814)
at Q (https://still-plains-1604.herokuapp.com/assets/application-b623e3dc11cb731dd5e417203ceb10d1.js:5:27124)
http://errors.angularjs.org/1.3.0/$injector/modulerr?p0=generosity&p1=Error…com%2Fassets%2Fapplication-b623e3dc11cb731dd5e417203ceb10d1.js%3A5%3A27124) application-b623e3dc11cb731dd5e417203ceb10d1.js:6
For clarity, "generosity" is the name of the app itself, which was defined in app.js.
Why would the module I defined be impossible to find in production, and not in local?
The app can be found at https://still-plains-1604.herokuapp.com/ literally any help with this issue would be a godsend.

Your source has a couple issues.
The HTML has two data-ng-app tags.
The angular-route file, which seems necessary for the app, isn't there.

Related

$resource is not changing the id of the url

I am in trouble to change the id param of a URL passed to $resource. Apparently the value isn't changing to the correct value that it recive from Resource.get(id:$routeParams.id), even when I put a fixed value (Resource.get(id:1)), resulting in the following error:
TypeError: encodeUriSegment is not a function
When I change the id param of the URL for a fixed value (baseURL+'client/1'), it works.
This is my font:
app.js
'use strict';
angular.module('serviceOrder',['ngRoute','ngResource'])
.config(function ($routeProvider,$locationProvider) {
/*$locationProvider.html5Mode({
enabled: true,
requireBase: false
});*/
$routeProvider.when('/clients', {
templateUrl: 'views/clients.html',
controller: 'ClientController'
});
$routeProvider.when('/newclient',{
templateUrl: 'views/client.html',
controller: 'NewClientController'
});
$routeProvider.when('/editclient/:id',{
templateUrl: 'views/client.html',
controller: 'EditClientController'
});
$routeProvider.otherwise({redirectTo: '/clients'});
});
controler.js
'use strict';
angular.module('serviceOrder')
.controller('EditClientController',['$scope','$routeParams','clientService',
function ($scope,$routeParams,clientService) {
$scope.message = 'Loading ...';
$scope.client = {};
$scope.phone = {id:'',brand:'',model:'',state:'',esn:''};
debugger;
clientService.getClients().get({id:$routeParams.id})
.$promise.then(
function (response) {
$scope.client = response;
},function (error) {
$scope.message = 'Error: ' + error;
}
);
}]);
service.js
'use strict';
angular.module('serviceOrder')
.constant('baseURL', 'http://localhost:8080/service-order-rest/rest/')
.service('clientService',['$resource','baseURL',function ($resource,baseURL){
this.getClients = function () {
return $resource(baseURL+'client/:id',null,{'update':{method:'PUT'}});
};
}]);
Your param defaults are not being configured properly. To achieve this, according to $resource's docs, you must especify the pattern of your API method that will receive params like { id: '#id' } instead of null.
$resource(baseURL + 'client/:id', //url
{ id: '#id' }, // parameters
{
'update': { method: 'PUT' } // methods
});
We have a bug here :
return $resource(baseURL+'client/:id',{id: youridhere} ,{'update':{method:'PUT'}});

How to handle http 302 response in angularjs

I have a java filter, that checks session attribute username. When the username is null then redirect to path /login.I access path /index.html when username is null, I got a HTTP code 302, so I add interceptor in angularjs. But I access /index.html got a error when username is null.
var testApp = angular.module('testApp', [ 'ngRoute', 'myApp' ]);
testApp.config([ '$routeProvider', function($routeProvider) {
$routeProvider.when('/anchor/historyAttendance/:uid',{
templateUrl : 'anchor/historyAttendance.html',
controller : 'AnchorHistoryAttendanceCtrl'
}).when('/anchor/list', {
templateUrl : 'anchor/list.html',
controller : 'AnchorListCtrl'
}).otherwise({
redirectTo : '/'
});
} ]);
var app = angular.module('myApp', [ 'ngTable', 'ngFileUpload', 'ngDialog' ,'ui.colorpicker', 'ngCsv', 'ngSanitize'],function ($provide,$httpProvider) {
// register the interceptor as a service
$provide.factory('myHttpInterceptor', function($q) {
return {
// optional method
'request': function(config) {
// do something on success
console.log(config);
return config;
},
// optional method
'requestError': function(rejection) {
// do something on error
console.log(rejection);
return $q.reject(rejection);
},
// optional method
'response': function(response) {
// do something on success
console.log(response);
return response;
},
// optional method
'responseError': function(rejection) {
// do something on error
console.log(rejection);
return $q.reject(rejection);
}
};
});
$httpProvider.interceptors.push('myHttpInterceptor');
});
app.directive('fontColor', function () {
return {
restrict: 'E',
scope: {},
replace: false,
template: '<div color-picker default-color="#ff0000" class="font-color" ng-style="{\'background-color\': selectedFontColor}"></div>',
link: function (scope) {
scope.selectedFontColor = '#f00';
scope.$on('colorPicked', function (event, color) {
scope.selectedFontColor = color;
});
}
}
});
the error in chrome like that:
You can not handle 302 response from a server because browsers do this before the Angular is notified. In a way, Angular response interceptor will never get a hand on this response.
It is properly explained here: Handle HTTP 302 response from proxy in angularjs or https://stackoverflow.com/a/29620184/2405040
It seems that you have created myApp after creation of testApp while you have injected myApp with testApp which does not look correct.
Make sure before injecting any of the module it should be available.
Try below code:
var app = angular.module('myApp', [ 'ngTable', 'ngFileUpload', 'ngDialog' ,'ui.colorpicker', 'ngCsv', 'ngSanitize'],function ($provide,$httpProvider) {
// register the interceptor as a service
$provide.factory('myHttpInterceptor', function($q) {
return {
// optional method
'request': function(config) {
// do something on success
console.log(config);
return config;
},
// optional method
'requestError': function(rejection) {
// do something on error
console.log(rejection);
return $q.reject(rejection);
},
// optional method
'response': function(response) {
// do something on success
console.log(response);
return response;
},
// optional method
'responseError': function(rejection) {
// do something on error
console.log(rejection);
return $q.reject(rejection);
}
};
});
$httpProvider.interceptors.push('myHttpInterceptor');
});
app.directive('fontColor', function () {
return {
restrict: 'E',
scope: {},
replace: false,
template: '<div color-picker default-color="#ff0000" class="font-color" ng-style="{\'background-color\': selectedFontColor}"></div>',
link: function (scope) {
scope.selectedFontColor = '#f00';
scope.$on('colorPicked', function (event, color) {
scope.selectedFontColor = color;
});
}
}
});
var testApp = angular.module('testApp', [ 'ngRoute', 'myApp' ]);
testApp.config([ '$routeProvider', function($routeProvider) {
$routeProvider.when('/anchor/historyAttendance/:uid',{
templateUrl : 'anchor/historyAttendance.html',
controller : 'AnchorHistoryAttendanceCtrl'
}).when('/anchor/list', {
templateUrl : 'anchor/list.html',
controller : 'AnchorListCtrl'
}).otherwise({
redirectTo : '/'
});
} ]);

How do inject services to Link function contained directive?

I am trying to inject services to the below directive which is used link function instead of controller.
(function() {
angular
.module("myApp")
.directive('myDirective',['$scope','myService','myData',function($scope,myService,myData) {
return {
restrict'AE',
replace:'true',
templateUrl :'/myApp/directive/my-directive',
scope: {
userId: "#"
}
},
link:function(scope,elem,attr)
{
//Code for link function goes here ...
scope.myUsersArray [];
scope.getUserDetails = function()
{
//code for getUserdetails goes here...
}
}
}]);
})();
When i run this code, i am getting exception like [$injector:unpr] Unkown Provider <_ $scope error. If i remove the injected services, i am not getting any error. Error throws at angular.js file so i don't have any clue to fix it :(
You have several syntax issues. Your code should look like this:
.directive('myDirective', ['$scope', 'myService', 'myData', function($scope, myService, myData) {
return {
restrict: 'AE',
replace: 'true',
templateUrl: '/myApp/directive/my-directive',
scope: {
userId: "#"
},
link: function(scope, elem, attr) {
//Code for link function goes here ...
scope.myUsersArray = [];
scope.getUserDetails = function() {
//code for getUserdetails goes here...
};
}
};
}]);
You may have more problems as its not evident as to why you are injecting $scope, myService, and myData

"No pending request to flush" in unit test for $asyncValidators using $http

I've yet to find an answer on SO, blogs or even Angular issues. I've got other services and controllers that use $http and $resource and their unit tests use $httpBackend.when() to mock the API and $httpBackend.flush() to return a response.
I'm having no luck with this directive, though.
I've created an asynchronous validator, based around the sample code in AngularJS docs. I have verified that the $http.get() is getting called before $httpBackend.flush() with console.log(). However, I get "No pending request to flush" for $httpBackend.flush(). Incidentally, I have also tried $httpBackend.expectGET(), and that expectation fails.
Directive code
'use strict';
angular.module('myApp')
.directive('myServerValidate', function ($q, $http) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attributes, ngModel) {
ngModel.$asyncValidators.server = function (modelValue, viewValue) {
return $http.get('http://myserver/api/System/ValidateField', {
params: {
field: scope.validationConfig.field,
value: '' + (modelValue || viewValue)
}
}).
then(function (successData) {
if (angular.isEmpty(successData) || angular.isEmpty(successData.Status)) {
return $q.reject();
} else if (!successData.Status) {
return $q.reject(successData.Message || '');
} else if (successData.Status) {
return $q.resolve(successData.Message || '');
}
}, function (rejectionData) {
return $q.reject(rejectionData);
});
};
}
};
});
Unit test
'use strict';
describe('Directive: myServerValidate', function () {
beforeEach(module('myApp'));
var form,
scope,
$httpBackend;
afterEach(function () {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
beforeEach(inject(function ($rootScope, $injector, $compile) {
scope = $rootScope.$new();
$httpBackend = $injector.get('$httpBackend');
$httpBackend.
when('GET', /ValidateField/).
respond(function () {
if (form.num === '1') {
return [200, {Status: true, Message: ''}, {}];
} else if (form.num === '2') {
return [200, {Status: false, Message: 'Invalid'}, {}];
} else {
return [404, {}, {}];
}
});
var element = angular.element('<form name="form">' +
'<input type="text" name="num" ng-model="model.num" hc-server-validate>' +
'</form>');
scope.model = {
num: null
};
scope.validationConfig = {
field: 'num'
};
$compile(element)(scope);
form = scope.form;
}));
it('should validate numeric value against server API', function () {
form.num.$setViewValue('1');
scope.$digest();
$httpBackend.flush();
expect(scope.model.num).toEqual('1');
expect(form.num.$valid).toBeTruthy();
});
});
I expected the scope.$digest() to kick off the validation (which it does), which would then call $http.get() (which happens), but $httpBackend somehow doesn't detect the call, or possibly $http doesn't generate the GET request.

Error: Unknown provider: SessionProvider <- Session AngularJS

I am aware that the error which is in the title of this question is basically because in my controller I am injecting a Session service in my controller that has not been defined. I am currently looking at: Angular Devise for which I am rolling out in an application that is using rails but have angular and rails separate. My setup on the angular side is as followed:
main.js
angular.module('App.controllers', []);
angular.module('App.config', []);
angular.module('App.directives', [])
angular.module('App.resources', ['ngResource']);
angular.module('App.services', []);
var App = angular.module("App", [
"ngResource",
"ngCookies",
"$strap.directives",
"App.services",
"App.directives",
"App.resources",
"App.controllers",
"TotemApp.config"
], function ($routeProvider, $locationProvider, $httpProvider) {
var interceptor = ['$rootScope', '$q', function (scope, $q) {
function success(response) {
return response;
}
function error(response) {
var status = response.status;
if (status == 401) {
window.location = "/login";
return;
}
return $q.reject(response);
}
return function (promise) {
return promise.then(success, error);
}
}];
});
Session.js
App.service('Session',[ '$cookieStore', 'UserSession', 'UserRegistration', function($cookieStore, UserSession, UserRegistration) {
this.currentUser = function() {
return $cookieStore.get('_angular_devise_user');
}
this.signedIn = function() {
return !!this.currentUser();
}
this.signedOut = function() {
return !this.signedIn();
}
this.userSession = new UserSession( { email:"sample#email.com", password:"password", remember_me:true } );
this.userRegistration = new UserRegistration( { email:"sample#email.com", password:"password", password_confirmation:"password" } );
}]);
sessions_controller
App.controller('SessionsController', ['$scope', '$location', '$cookieStore', 'Session', function($scope, $location, $cookieStore, Session) {
$scope.session = Session.userSession;
$scope.create = function() {
if ( Session.signedOut ) {
$scope.session.$save().success(function(data, status, headers, config) {
$cookieStore.put('_angular_devise_user', Session.userSession.email);
$location.path('/todos');
});
}
};
$scope.destroy = function() {
$cookieStore.remove('_angular_devise_user');
$scope.session.$destroy();
};
}]);
routes.js
'use strict';
App.config(function($routeProvider, $httpProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main/home.html',
controller: 'MainCtrl'
})
.when('/login', {
templateUrl: 'views/sessions/new.html',
controller: 'SessionsController'
})
.when('/sign_up', {
templateUrl: 'views/registrations/new.html',
controller: 'RegistrationsController'
})
.otherwise({
redirectTo: '/'
});
});
This error occurs when I try to access the login page or register page. If someone can shed some light that would be greatly appreciated. Not entirely sure how to resolve this Error: Unknown provider: $SessionProvider <- $Session error
At first glance this looks correct. I can only assume that perhaps you've not included Session.js in your index.html file?
Angular clearly doesn't know what 'Session' service is so there's something wrong there either file not loaded, not loaded correctly or something along those lines as far as I can see.
Edit: Does the error say 'SessionProvider <- Session' or '$SessionProvider -< $session' because if it's the latter, then something is named wrong somewhere in your app since your service is named 'Session' not '$Session'.
When you have syntax error in other javascript or typescript files. You will get the same error. Please make sure that you have no syntax error.

Categories

Resources