I am trying to create a AngularJS and WEB API application but this is my first time. I am getting following error...
0x800a1391 - JavaScript runtime error: 'MyApp' is undefined
My AngularJS Service file is like below and this is where it gives the error above...
MyApp.factory('CityService', ['$http', function ($http) {
var urlBase = 'http://localhost:58057/api';
var CityService = {};
CityService.getCities = function () {
return $http.get(urlBase + '/Cities');
};
return CityService;
}]);
Where should I define MyApp?
Related
I have been trying to inject $log in to a component created by a require statement for some client Angular.
var App = require('./app/containers/App');
var Header = require('./app/components/Header');
require('angular-ui-router');
var routesConfig = require('./routes');
import './index.css';
angular
.module('app', ['ui.router'])
.config(routesConfig)
.controller(App.App, ['$log'])
.service('todoService', todos.TodoService)
.component('app', App)
.component('headerComponent', Header);
The code for header is
module.exports = {
template: require('./Header.html'),
controller: Header,
bindings: {
todos: '='
}
};
/** #ngInject */
function Header(todoService) {
this.todoService = todoService;
}
Header.prototype = {
handleSave: function (text) {
if (text.length !== 0) {
this.todos = this.todoService.addTodo(text, this.todos);
}
}
};
~
The code for App is
module.exports = {
template: require('./App.html'),
controller: App
};
function App($log) {
this.log = $log;
$log.error('Hello from App');
}
I can inject $log as dependency for App as I have access to the controller. But attempting the same task for Header is difficult,because Header is created by require which does not seem to allow access to the controller function.
What I like to know is there a way round this?
I am trying to find a way of logging information from any possible javascript function in header.js.
I have seen any alternatives other than using $log to log information in a client side application
My solution so far has been to say in code written in the require block.
var ing = angular.injector(['ng']);
this.$log = ing.get('$log');
this.$log.error('I am a message');
I think this is the wrong way of doing things, it gives me what I want, but I expect it will break at some point. I find having access to $log is useful for debugging only. Its not sort of thing I need for any production code.
All I was trying to do was to get access to the $log angular wrapper. Turns out all I had to do was add $log to the argument list.
function Header(todoService,$log) {
$log.log('I am a log message');
this.todoService = todoService;
}
I am bit of a Angular 1.5 newbie and I had assume that you had to inject the $log to get the right response. Just declare it seems to be a bit of a kop out.
i've been searching around for the last days but i cannot get closer to the solution. I try to mock the http response requested by the angular controller.
angular controller:
myController = function ($http, appConfig) {
$http.post(appConfig.restPath+"/administration/imports", {
}).then(function(data){
$scope.pagination = data;
$scope.totalItems = data.data.content.length;
$scope.totalPages = data.data.totalPages;
$scope.pages = [];
$scope.imports = data.data;
for (var i = 0; i < $scope.totalPages; i++){
$scope.pages.push(i);
}
});
}
and the test:
describe('Controller: myController', function() {
// load the controller's module
beforeEach(module("myModule"));
var controller,
scope, httpBackend, myPost;
// Initialize the controller and a mock scope
beforeEach(inject(function ($injector) {
httpBackend = $injector.get('$httpBackend');
myPost = httpBackend.whenPOST('http://localhost:9000/api/v1/administration/imports').respond({data: {content: ["a", "b"], totalPages: "1"}}, "");
scope = $injector.get('$rootScope');
var $controller = $injector.get('$controller');
createController = function() {
return $controller(myController, {'$scope' : scope });
};
}));
afterEach(function() {
httpBackend.verifyNoOutstandingExpectation();
httpBackend.verifyNoOutstandingRequest();
});
it('should browse the list of imported files', function() {
httpBackend.expectPOST('http://localhost:9000/api/v1/administration/imports');
var controller = createController();
httpBackend.flush();
});
});
But it seems that he wants to ask the server for the real data when i inspect the test in the chrome console (network traffic -> HTTP requests shows me, that he is requesting the server instead of loading the mocked data...), but he receives 403 (forbidden).
the error i receive by karma is the following:
TypeError: Cannot read property 'length' of undefined at myController.js:35:40
line 35 is:
$scope.totalItems = data.data.content.length;
that makes me think that he tries to load the data from the REST service, receives 403, empty result (means data == {}) and then he tries to access on data.data.content.length which is undefined....
as you can see i did it exactly like google it recommends...
https://docs.angularjs.org/api/ngMock/service/$httpBackend
Other examples on SO or anywhere else look quite similar. What am i doing wrong?
yes you have to provide the real data or at least you can provide a prototype pf your data because you are testing that unit and it requires length.
and remove this part because you are mocking it twice
httpBackend.expectPOST('http://localhost:9000/api/v1/administration/imports');
use
myPost = httpBackend.expectPOST('http://localhost:9000/api/v1/administration/imports').respond({data: {content: ["a", "b"], totalPages: "1"}}, "");
this way you make sure that post is being called but if you still get same error then you have to check respond data.
I tried to set a new controller in my Angular app, but I have this error coming:
[$injector:unpr] http://errors.angularjs.org/1.4.2/$injector/unpr?p0=successRedirectProvider%20%3C-%20successRedirect%20%3C-%20ingreCtrl.
I tried many things for a few hours but still have this issue.
Here's my files:
app.js:
var app = angular.module('app', ['formSubmit']);
app.factory('successRedirect', function(){
return function(data) {
if(data.status === "success") {
alert(data.message);
if (typeof(data.redirect) !== "undefined"){
document.location.href = data.redirect;
}
}else{
}
};
});
app.factory('errors', function(){
return function(data) {
alert(data.message)
for(var i = 0; i<data.errors.length;i++){
$('#new-page-form-container').append('<p>'+data.errors[i]+'</p>');
}
};
});
formApp.js:
var formSubmit = angular.module('formSubmit', ['ckeditor', 'ngFileUpload']);
ingredientsCtrl.js:
formSubmit.controller('ingreCtrl', ['$scope', '$filter', '$http', 'successRedirect', 'errors', function ($scope, $filter, $http, successRedirect, errors) {
}]);
You're trying to use the successRedirect service of the app module inside your formSubmit module. That means you need to dependency inject app into formSubmit:
var formSubmit = angular.module('formSubmit', ['app', 'creditor', 'ngFileUpload']);
^^^^^
Not the other way around.
I finally found why it doesn't work, last week I did another module for the login system in my web site in another file, and I didn't remember that I already gave the name 'app' to this module, so I change my module's name in the file app.js and it works.
But to answer to some comments, my dependency injection was good, as my inclusion, no need to change the order. The problem was the module name.
Thanks anyway for your time, subject close ^^
I'm writing angular unit tests using Jasmine with angular-mocks' httpBackend.
I've managed to properly mock my backend but some one of my tests has some issues with an http call where a value is set to scope after the request is done (in then()).
Controller:
$scope.startShift is binded to a button click.
app.controller('ShiftStartCntl', function($scope, $rootScope, $location, Restangular, $http, shifts) {
$scope.shifts = shifts;
$scope.startShift = function (category) {
$scope.startingShift = true;
baseShifts.post({category_number: 2})
.then(function (shift) {
$scope.shift = shift;
// breaks here if run as the endpoint isn't mocked
$http.post('endpointThatIsNotMocked').then(function() {});
$location.path($scope.rootURL + '/shift/' + shift.id + '/');
$scope.startingShift = false;
});
});
Test:
// module definition and stuff
//
// [...]
//
describe('ShiftStartCntl', function() {
var scope, rootScope, httpBackend, ShiftStartCntl;
beforeEach(angular.mock.inject(function($rootScope, $controller, $httpBackend) {
scope = $rootScope.$new();
rootScope = $rootScope;
httpBackend = $httpBackend;
// mimics the controller's ng-route `resolve` dependency
shifts = getJSONFixture('leave_shifts.json');
scope.baseShifts = baseApi.all('shifts');
// used in the controller
scope.categories = getJSONFixture('leave_categories.json');
httpBackend.expectPOST('/api/shifts/', {category_number: 2})
.respond(203, {"id": 4, "user": 1,
"category_number": 2,
"sign_in": "2015-02-10T21:29:06.110Z",
"sign_out": null
});
$controller('ShiftStartCntl', {$scope: scope, shifts: []});
}));
it('should start a shift', function() {
expect(shifts.length).toEqual(2);
expect(scope.startingShift).toBe(undefined);
scope.startShift(scope.categories[1]);
rootScope.$apply();
expect(scope.shift.id).toEqual(4);
httpBackend.flush();
});
});
The produced error is the following:
PhantomJS 1.9.8 (Mac OS X) Shifts ShiftStartCntl should start a shift FAILED
Expected undefined to equal 4.
at [...]/js/tests/unit/controllers/main.js:100
Error: Unexpected request: POST yoyoyo
which is the line where expect(scope.shift.id).toEqual(4);
My problem is that the error about the unexpected request should happen before expect(scope.shift.id).toEqual(4); is executed.
As read in several Stackoverflow answers and various blogposts, I've tried using $rootScope.apply(); with no success.
Any ideas on how this could be solved?
Can you try to move the httpBackend.flush(); two lines above
scope.startShift(scope.categories[1]);
httpBackend.flush();
rootScope.$apply();
expect(scope.shift.id).toEqual(4);
I have a service like the folowing one:
var app = angular.module('app');
app.service('messagingService', function($http){
this.getMessages = function(offset, limit, successCallback, errorCallback){
// some stuff goes here
};
});
I include this file and afterwards I include my controller file.
My controller starts like this
function Inbox($scope, $http, messagingService) {
}
But when I load my page I get the following error:
Error: [$injector:unpr] http://errors.angularjs.org/undefined/$injector/unpr?p0=messagingServiceProvider%20%3C-%20messagingService
at Error ()
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:6:453
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:32:320
at Object.c [as get] (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:29:461)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:32:388
at c (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:29:461)
at d (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:30:130)
at Object.Xb.instantiate (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:31:284)
at $get (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:61:304)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:48:476
When I use my service code in same file as the controller it works well. What am I missing here? Thanks
you need to attach your controller to your module.
var app = angular.module('app');
app.service('messagingService', function($http){
this.getMessages = function(offset, limit, successCallback, errorCallback){
// some stuff goes here
};
});
app.controller('Inbox',['$scope', '$http', 'messagingService',function($scope, $http, messagingService){}])
Good way is to inject the service as dependency for eg:
var app = angular.module('ur_app_name')
app.service('messagingService', function($http){
this.getMessages = function(offset, limit, successCallback, errorCallback){
//some stuff goes here
};
app.controller('GreetingController', ['$scope','messagingService' function($scope,messagingService) {
//something here
})
Try the following:
var app = angular.module('app', ['app.services']);
in your app.js
and then in your services.js
var services = angular.module('app.services');
services('messagingService', function($http){....