I'm currently creating a game with Javascript and HTML using an MVC design pattern. However, when uploading to the cafe I'm using, I keep getting an error that my View.js class is not being defined in the Controller.js class. However, as by the snippet of code below, you can see that it is:
"use strict";
var model = new Model(),
view = new View(),
controller = null;
function Controller(){
this.init = function(){
view.playGame();
}
}
I also have included the relevant javascript classes within script tags on the single html sheet I'm using. The error message I get in the Chrome debugger is "Uncaught ReferenceError View not defined in Controller.js" Does anybody know why this has started happening? As I have been working on this project for a while and this is the first time it has happened.
I'm very new to Angular and I'm trying to figure much of this out still. I'm writing some tests using Angular 1.5.8 which I generated from the Yeoman Generator.
Specifically, I'm trying to figure out how to manipulate $httpBackend results (I'm not sure if that's important or not)...
In my app.js file I have the following code:
.run(['$rootScope', '$location', 'breadcrumbService', function ($rootScope, $location, breadcrumbService) {
$rootScope.$on('$viewContentLoaded', function () {
jQuery('html, body').animate({scrollTop: 0}, 200);
});
$rootScope.isEditMode = false;
$rootScope.$on('$stateChangeSuccess', function () {
// ------------ this next line is failing -----------
$rootScope.isEditMode = $location.path().toLowerCase().endsWith('/edit') || $location.path().toLowerCase().endsWith('/new');
});
$rootScope.parseJson = function (value) {
return angular.fromJson(value);
};
$rootScope.bc = breadcrumbService;
$rootScope.title = "";
}])
The line about halfway down (where I added the comment) is failing. Specifically, the endsWith function is failing (toLower is fine), with this error:
PhantomJS 2.1.1 (Windows 8 0.0.0) Service: breadcrumbService should return breadcrumb label in json format FAILED
TypeError: undefined is not a constructor (evaluating '$location.path().toLowerCase().endsWith('/edit')') in app/scripts/app.js (line 44)
app/scripts/app.js:44:72
$broadcast#bower_components/angular/angular.js:18005:33
bower_components/angular-ui-router/release/angular-ui-router.js:3353:32
processQueue#bower_components/angular/angular.js:16383:30
bower_components/angular/angular.js:16399:39
$eval#bower_components/angular/angular.js:17682:28
$digest#bower_components/angular/angular.js:17495:36
$apply#bower_components/angular/angular.js:17790:31
done#bower_components/angular/angular.js:11831:53
handleResponse#bower_components/angular-mocks/angular-mocks.js:1368:17
flush#bower_components/angular-mocks/angular-mocks.js:1808:26
test/spec/services/breadcrumbservice.js:33:27
invoke#bower_components/angular/angular.js:4718:24
workFn#bower_components/angular-mocks/angular-mocks.js:3085:26
Here is my test code (some junk modified from different examples - just trying to get it to work):
'use strict';
describe('Service: breadcrumbService', function () {
// load the service's module
beforeEach(module('myModule'));
var $httpBackend, $rootScope, createController, authRequestHandler;
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
console.log('Is null? '+ ($httpBackend == null));
$httpBackend.whenGET(/views\/.*/).respond(200, [{}, {}, {}]);
authRequestHandler = $httpBackend.when('GET', '/api/v1/SiteStagings')
.respond({userId: 'userX'}, {'A-Token': 'xxx'});
// Get hold of a scope (i.e. the root scope)
$rootScope = $injector.get('$rootScope');
$httpBackend.flush();
}));
// instantiate service
var breadcrumbService;
beforeEach(inject(function (_breadcrumbService_) {
breadcrumbService = _breadcrumbService_;
}));
it('svc should exist', function () {
expect(!!breadcrumbService).toBe(true);
});
it('should return breadcrumb label in json format', function () {
var result = breadcrumbService.getFromCache('site', 'SiteGroupStagings', 46, 'SiteGroupDesc');
console.log(result);
expect(!!result).toBe(true);
});
});
I don't doubt that I'm doing something wrong here, I just can't quite understand what it is. What does this error really mean and why does it not like my call to endsWith?
Thanks
undefined is not a constructor
is an error message PhantomJS displays when you tried to call a function that is not defined. It depends on the version of ECMAScript which your PhantomJS supports. So as you said it works fine in Chrome, because this browser supports the function you are using in test.
In order to fix your problem and still be able to use PhantomJS you can replace the "unknown to PhantomJS" function with some alternative function.
I was getting TypeError: undefined is not a constructor error using the includes() method. The includes() and endsWith() methods are new in ECMAScript 2015, and are not supported in Internet Explorer, and evidently not by PhantomJS.
There is a chance your end user may be using Internet Explorer. In which case, you may want to use the fully supported indexOf() method instead of includes() or endsWith()
For example, in my case, everything worked great in chrome, but my tests were failing on the line:
if (item.name.includes('contents'))
I changed to using the indexOf() method instead:
if (item.name.indexOf('contents') !== -1)
And then I was no longer getting the error
TypeError: undefined is not a constructor
I debated whether or not to post this as an answer or just an edit to my question, but I guess it's my answer (for now):
It seems the problem is related to PhantomJS. As soon as I changed the engine to Chrome in the karma.conf.js file, those tests passed.
I still don't know what that error message is supposed to mean and why it wasn't working with PhantomJS, but at least I'm now able to continue.
Here are the modifications to my karma.conf.js (in case anyone is curious):
browsers: [
//'PhantomJS',
'Chrome'
],
// Which plugins to enable
plugins: [
'karma-chrome-launcher',
//'karma-phantomjs-launcher',
'karma-jasmine'
],
Btw - I did notice that endsWith is new to ECMAScript6 (I was thinking it was older), but WebStorm shows that it's referencing a helper function in angular-ui-grid. I spent quite a while messing with the files array in the karma.conf.js file in an attempt to see if the ui-grid dependency was loading too late or something. In every test, it worked fine in Chrome but not PhantomJS. I still have no idea why.
In My Case: Cyclic Dependencies Causing:
PhantomJS 2.1.1 (Windows 8 0.0.0) ERROR TypeError: undefined is not a constructor (evaluating '(0, _actions.prefix)('SET_USER_INPUT_PHONE_NUMBER')') at undefined:12
I got the same error after I added imports in my javascript production code (ES6 syntax compiled with babel/webpack).
The changes were fine when a production build of the application was loaded in chrome but running the tests with phantomJS produced the error.
In my case the added imports created cyclic dependencies.
I'm dropping this here for future reference (I stumbled upon the same problem a few weeks ago and don't want to scratch my head again in another couple of weeks) and for others that google the same error.
I faced similar error with PhantomJS:
For me the error was the way in which I was creating a spy object for my service.
Error on line in code file new Service.getData(param1, param2)
Fix in test file: jasmine.createSpyObj('Service',['getData'])
What is was missing was adding ['getData] while creating spyObj
I started using Later.js Library recently and am facing this issue on using 'isValid' function on a composite Schedule. Since I am new to this, I am likely making some common mistake. Please guide for the same. I am adding the code snippet and the error message below.
var schedule =
later.parse.recur()
.on(25).dayOfMonth().on(5).month().on(2016).year()
.and()
.on(26).dayOfMonth().on(5).month().on(2016).year()
.and()
.on(27).dayOfMonth().on(5).month().on(2016).year()
var sched = later.schedule(schedule);
var ans = sched.isValid(new Date('2016-05-27'));
console.log(ans);
Here is the error message
f:\Projects\DragonFly\node_modules\later\later.js:777
return !b || a.getTime() > b.getTime();
^
TypeError: a.getTime is not a function
at f:\Projects\DragonFly\node_modules\later\later.js:777:24
at findNext (f:\Projects\DragonFly\node_modules\later\later.js:785:23)
at getInstances (f:\Projects\DragonFly\node_modules\later\later.js:637:52)
at Object.later.schedule.sched.isValid (f:\Projects\DragonFly\node_modules\later\later.js:793:16)
at Object.<anonymous> (f:\Projects\DragonFly\Controllers\scheduleController.js:76:17)
I updated my Later.js to the latest version with no success. Please tell me if I am making any mistake in the code, or is it a bug in the library itself?
I'm following the Todomvc exercise from the Developing BackboneJS Applications book and reached a point to test if what I have so far is working by testing through JavaScript console.
When I type window.app.Todos.create({ title: 'My first Todo items'}); into the console I get an error Uncaught TypeError: undefined is not a function related to app.js:67. The code there is
addOne: function( todo ) {
var view = new app.TodoView({ model: todo });
$('#todo-list').append( view.render().el );
},
I have a few files posted but this is my Github repository https://github.com/gnazarkin/todomvc.
I was trying to make by myself a "library" for my personal project which uses local storage for nearly everything and I got this error.
The Browser I am using is Google Chrome on the last version. It says no error line on the console and the error is:
TypeError: Cannot call method 'addL' of undefined.
JavaScript
function local (title) {
var storeTitle = title;
this.addL = function(lString) {
var storeText = lString;
localStorage.setItem(storeTitle, storeText);
};
this.removeL = function() {
localStorage.removeItem(storeTitle);
};
this.getL = function () {
localStorage.getItem(storeTitle);
};
};
I can't find the error and when I google Cannot call method ... of undefined it shows a lot of pages but with different content, not the one I'm looking for. I found from Google Maps API to jQuery API.
I learned this "way" from another question here StackOverflow.
You are missing the new keyword. So try this:
new local("locally").addL("stored")