AngularJs: Implemented IIFE in using ui router - javascript

I'm trying to implement iife and this style to seperate my files in angularjs so I have config.js that will use ui.router that was implemented this way
//config.js
(function (module) {
"use strict";
module.config([
"$stateProvider","$urlRouterProvider","$locationProvider",
function ($stateProvider, $urlRouterProvider,$locationProvider) {
$urlRouterProvider.otherwise("/Views/Profile.html");
$stateProvider
.state("profile", {
url: "/",
templateUrl: "Profile.html",
controller: "profileController as vm"
})
.state("profiledetails", {
url: "ProfileDetails",
templateUrl:"ProfileDetails.html",
controller: "profileController as vm"
})
}
])
})(angular.module("appMain", ["ui.grid","ui.router","profileService"]));
and I have this profile.html which has a link to profiledetail.html
<!DOCTYPE html>
<html ng-app="appMain">
<head>
<title></title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link href="../Content/ui-grid.css" rel="stylesheet" />
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body class="container-fluid">
<div ng-controller="profileController">
<div id="profileGrid" ui-grid="gridOptions"></div>
</div>
<script src="../scripts/angular.js"></script>
<script src="../scripts/angular-ui-router.js"></script>
<script src="../scripts/angular-resource.js"></script>
<script src="../scripts/ui-grid.min.js"></script>
<script src="../scripts/App/config.js"></script>
<script src="../scripts/App/Profile/profileService.js"></script>
<script src="../scripts/App/Profile/profileController.js"></script>
<script src="../scripts/App/helper.js"></script>
profile details
<div ui-view></div>
</body>
</html>
And this is my profilecontroller.js
(function(module) {
"use strict";
module.controller("profileController", ["$scope", "profileService", profileController]);
function profileController($scope, profileService) {
var vm = this;
var scope = $scope;
vm.profiles = getProfiles;
var onProfiles = [{
firstName: "Juan",
lastName: "Dela Cruz"
}, {
firstName: "Andres",
lastName: "Cruz"
}];
function getProfiles() {
profileService.getProfiles()
.then(onProfiles(result));
};
scope.gridOptions = {
enableSorting: true,
columnDefs: [{
name: "firstName",
field: "firstName"
}, {
name: "lastName",
field: "lastName"
}],
data: onProfiles
};
}
}(angular.module("appMain")));
In running the code and upon click to the link theres an error in chrome saying "Error: Could not resolve 'profiledetails' from state ''". Not sure if my implementation of iife caused this issue. Please someone guide me to the correct path.

You don't need to re-inject the module's dependencies when creating the profileController, and the iife parameter should immediately follow the closing curly bracket, so:
})(angular.module("appMain", ["profileService", "ui.grid","ui.router"]));
can become:
}(angular.module("appMain")));
This way you're retrieving the previously created module, rather than creating a new one. See the Creation versus Retrieval section of the docs for a note on this.
Also onProfiles is an array (not a function), so I think you need to change this:
function getProfiles() {
profileService.getProfiles()
.then(onProfiles(result));
};
To something more like this:
function getProfiles() {
profileService.getProfiles()
.then(function(result){
// do something with the "onProfiles" array here.
});
};

You use the same controller in your profile detail which is profileController
So in your html you should add
profile details
<div ui-view></div>
So that routing to profile detail can process

Related

(AngularJS) Can't inject factory into controller

I'm trying to inject my factory into a controller. If I list the factory as one of the controller's parameters, I get this error:
Error: [$injector:unpr] Unknown provider: wordRushFacProvider <- wordRushFac <- wordrushCtrl
http://errors.angularjs.org/1.6.1/$injector/unpr?p0=wordRushFacProvider%20%3C-%20wordRushFac%20%3C-%20wordrushCtrl
Here is the code for my factory:
(function() {
"use strict";
angular
.module("wordrush")
.factory("wordRushFac", function($http) {
function getValidWords() {
return $http.get('../data/valid-words.txt');
}
return {
getValidWords : getValidWords
}
})
})
And the code for my controller:
(function() {
'use strict'
angular
.module('wordrush')
.controller('wordrushCtrl', function($scope, $http, wordRushFac) {
wordRushFac.getValidWords().then(function(words) {
$scope.words = words.data;
});
$scope.words = 'Hello'
});
})();
And for my index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Word Rush</title>
<link rel="stylesheet" href="node_modules/angular-material/angular-material.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="node_modules/angular/angular.js"></script>
<script src="scripts/app.js"></script>
<script src="components/wordrush.ctr.js"></script>
<script src="components/wordrush.fac.js"></script>
</head>
<body ng-app="wordrush" ng-controller="wordrushCtrl">
<h1> {{ words }} </h1>
</body>
</html>
And for my app.js:
angular
.module('wordrush', ['ngMaterial'])
.config(function($mdThemingProvider) {
$mdThemingProvider.theme('default')
.primaryPalette('blue')
.accentPalette('green');
})
I made a program with code identical to this except the names and variables were changed, and it worked fine. So what am I doing wrong here?
Here is a plunkr that says "Hello": https://plnkr.co/edit/MyxcXQ8YI4QYqeFsyVJz?p=preview
You have an extra set of open / close parenthesis in your controller definition, remove those:
angular
.module('wordrush')
.controller('wordrushCtrl', function($scope, $http, wordRushFac) {
wordRushFac.getValidWords().then(function(words) {
$scope.words = words.data;
});
$scope.words = 'Hello'
});
Also, are you sure you are including the ng-material JS file? I didn't see that listed in your HTML.
You're not injecting in the controller, should be:
.controller('wordrushCtrl', ['$scope', '$http', 'wordRushFac', function($scope, $http, wordRushFac) {
// Rest of controller code;
}]);
Switch your scripts. Factory script should be first then controller
Ther order should be,
<script src="scripts/app.js"></script>
<script src="components/wordrush.fac.js"></script>
<script src="components/wordrush.ctr.js"></script>
DEMO
I made the following changes and it worked fine.
(function() {
"use strict";
angular
.module("wordrush")
.factory("wordRushFac", function($http) {
function getValidWords() {
return $http.get('../data/valid-words.txt');
};
return {
getValidWords : getValidWords
};
});
}());

Keep getting AngularJS module not available (ASP.NET 5)

Trying to get simple Angular DI working in an existing ASP.NET 5 (Core) project.
Been following this tutorial.
Versions:
AngularJS 1.4.6
ASP.NET 5 (vNext)
Visual Studio 2015
Windows 10
Checked all the basic gotchas with naming and so on. Unclear about how my dependent js-files "controllers.js" & "services.js" are suppose to be discovered by Angular?
If I explicitly include them - which by the tutorial shouldn't be required - I still get
[ng:areq] Argument 'customerController' is not a function, got
undefined
Index.html
<!DOCTYPE html>
<html ng-app="bonusapp">
<head>
<meta charset="utf-8" />
<link href="lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="lib/bootswatch/yeti/bootstrap.min.css" rel="stylesheet" />
<link href="css/main.css" rel="stylesheet" />
<script type="text/javascript" src="lib/angular/angular.js"></script>
<script type="text/javascript" src="lib/angular-resource/angular-resource.js"></script>
<script type="text/javascript" src="lib/angular-route/angular-route.js"></script>
<script src="lib/app.js"></script>
<!--<script>angular.bootstrap(document, ['app']);</script>-->
</head>
<body ng-cloak>
<div id="wrapper" ng-controller="customerController">
<div id="main" class="container-fluid">
<div class="row">
<div class="col-md-3">
<h2>Kunder</h2>
<ul>
<li ng-repeat="item in Models">
{{item.FirstName}} {{item.LastName}} <a>Redigera</a> <a>Radera</a>
</li>
</ul>
</div>
</div>
</div>
<script type="text/javascript" src="lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="lib/bootstrap/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="lib/jquery-validation/dist/jquery.validate.js"></script>
<script type="text/javascript" src="lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</body>
</html>
app.js
(function () {
'use strict';
// Define module "app"
angular.module('bonusapp', [
// Angular modules
'ngRoute',
'ngResource',
// Custom modules
'customerService'
// 3rd Party Modules
]);
})();
controllers.js
(function () {
'use strict';
// Assign controller to app
angular
.module('bonusapp')
.controller('customerController', [
customerController]);
// $inject() method call is required to enable the controller to work with minification.
customerController.$inject = [
'$scope',
'Customers'
];
// Construct controller
function customerController($scope, Customers) {
// Populate model from service
$scope.Models = Customers.get();
}
})();
services.js
(function() {
'use strict';
var customerService =
angular
.module('customerService', ['ngResource']);
customerService
.factory('Customers',
['$resource'],
function ($resource) {
return $resource('/api/customers', {}, {
// Service call to get Customers
get: {
method: 'GET',
params: {},
isArray: true
}
});
}
);
})();
As Win suggested, I needed to:
Fix the include order to put jQuery first
Include all my JS files
But I still had some issues. For reference, here are the fixed scripts:
controller.js
(function () {
'use strict';
// Construct controller
// Remarks: controller is now declared FIRST
var customerController = function ($scope, Customers) {
$scope.Title = "Title";
// Populate model from service
$scope.Models = Customers.get();
}
// $inject() method call is required to enable the controller to work with minification.
customerController.$inject = [
'$scope',
'Customers'
];
// Assign controller to app
angular
.module('bonusapp')
.controller('customerController',
customerController);
})();
services.js
(function() {
'use strict';
var customerService =
angular
.module('customerService',
['ngResource']);
customerService
.factory('Customers',
['$resource',
function ($resource) {
return $resource('/api/customers', {}, {
// Service call to get Customers
// Remarks: 'get' in single quotes
'get': {
method: 'GET',
params: {},
isArray: true
}
});
}
]);
})();
You need to include controller.js and services.js files.
In addition, you need to move jquery before angular.js.
<script type="text/javascript" src="lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="lib/angular/angular.js"></script>
<script type="text/javascript" src="lib/angular-resource/angular-resource.js"></script>
<script type="text/javascript" src="lib/angular-route/angular-route.js"></script>
<script src="lib/app.js"></script>
<script src="lib/controllers.js"></script>
<script src="lib/services.js"></script>
FYI: You might also want to look into bundling and magnification, before you publish.

inline javascript within angular directive template url

I'm trying to embed the dalliance genome browser into an Angular application.
It works fine when placed on the main page.
However, because the app is large, I am trying to use a Template-expanding directive.
I read some posts about inline javascript not playing well along Angular, and the solution. In particular I added this gist to my app.
My app now looks like this plunker.
Question: The genome browser plugin does not appear :-( What's wrong?
app.js:
(function(angular) {
'use strict';
angular.module('docsTemplateUrlDirective', [])
.controller('Controller', ['$scope', function($scope) {
$scope.title = "Genome Browser";
}])
.directive('genomeBrowser', function() {
return {
templateUrl: 'genomeBrowser.html'
};
});
})(window.angular);
genomeBrowser.html:
<h2>Embedded page:</h2>
<script type='text/javascript-lazy' language="javascript">
new Browser(options);
</script>
<div id="svgHolder"></div>
(The options are not relevant here but can be seen in the plunker.)
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Genome browser</title>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="app.js"></script>
<script src="angular-loadscript.js"></script>
<script src="http://www.biodalliance.org/release-0.13/dalliance-compiled.js"></script>
</head>
<body ng-app="docsTemplateUrlDirective">
<div ng-controller="Controller">
<h1>{{title}}</h1>
<div genome-browser></div>
</div>
</body>
</html>
You forgot to include 'ngLoadScript' as a dependency:
angular.module('docsTemplateUrlDirective', [])
should be
angular.module('docsTemplateUrlDirective', ['ngLoadScript'])
Also, there was a missing quote in your partial in console.log('debug');
To solve this, I moved all inline javascript into the directive.
app.js:
(function() {
'use strict';
angular.module('app', []);
angular.module('app').controller('mainCtrl', ['$scope', function($scope) {
$scope.title = "Genome Browser";
}]);
angular.module('app').directive('genomeBrowser', function() {
return {
templateUrl: 'genomeBrowser.html',
restrict: 'E',
controller: function($scope) {
var browser = new Browser({
pageName: 'dalliance', // Target element ID.
chr: '22',
viewStart: 30000000,
viewEnd: 30030000,
cookieKey: 'human',
coordSystem: {
speciesName: 'Human',
taxon: 9606,
auth: 'NCBI',
version: '36',
ucscName: 'hg18'
},
sources: [{
name: 'Genome',
uri: 'http://www.derkholm.net:8080/das/hg18comp/',
tier_type: 'sequence',
provides_entrypoints: true
}, {
name: 'Genes',
desc: 'Gene structures from Ensembl 54',
uri: 'http://www.derkholm.net:8080/das/hsa_54_36p/',
collapseSuperGroups: true,
provides_karyotype: true,
provides_search: true
}, {
name: 'Repeats',
uri: 'http://www.derkholm.net:8080/das/hsa_54_36p/',
stylesheet_uri: 'http://www.derkholm.net/dalliance-test/stylesheets/ens-repeats.xml'
}, {
name: 'MeDIP raw',
uri: 'http://www.derkholm.net:8080/das/medipseq_reads'
}, {
name: 'MeDIP-seq',
uri: 'http://www.ebi.ac.uk/das-srv/genomicdas/das/batman_seq_SP/'
}]
});
}
};
});
})();
genomeBrowser.html:
<div id="dalliance"></div>
I still have things to learn about how to properly control this browser my for next homework, but this answers the question.
Plunk: http://plnkr.co/edit/KSUVq8?p=preview

Getting Jasmine to Work with Angular JS

I am trying to get Jasmine to work with my Angular JS Project But I always keep getting the following error. I am trying to get it to run a very very simple test. Also I have setup the angular js project using RequireJS. I have given my code below.
The Error I get is :
My Very Simple TestSpec is as given below :
describe('Controller:UserController', function () {
var scope,controller;
beforeEach(function () {
module('app');
inject(function ($controller,$rootScope) {
scope = $rootScope.$new();
controller = $controller('UserController', { '$scope': scope });
});
});
it('checks the troller name', function () {
expect(scope.name).toBe('Superhero');
});
});
And My Controller code is as given below :
define(['app','WebCallManager'], function (app) {
app.controller('UserController', function ($scope,$location,webcallService) {
$scope.name = 'Superhero';
$scope.loginUser = function(){
console.log("Login User Called...");
$location.path('/login').replace();
console.log("View Navigated...");
};
$scope.slidePanel = function(){
f7.openPanel('left');
};
$scope.doWebCall = function(){
console.log("Doing the Web Call...");
webcallService.sendGetRequest();
};
});
});
And the TestRunner.html is :
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Test Runner v2.0.1</title>
<link rel="shortcut icon" type="image/png" href="framework/lib/jasmine-2.0.1/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="framework/lib/jasmine-2.0.1/jasmine.css">
<!-- Jasmine/Angular testing framework libraries -->
<script type="text/javascript" src="framework/lib/jasmine-2.0.1/jasmine.js"></script>
<script type="text/javascript" src="framework/lib/jasmine-2.0.1/jasmine-html.js"> </script>
<script type="text/javascript" src="framework/lib/jasmine-2.0.1/boot.js"></script>
<script type="text/javascript" src="framework/lib/angular.js"></script>
<script type="text/javascript" src="framework/lib/angular-mocks.js"></script>
<!-- include source files here... -->
<script data-main="main" src="framework/lib/require.js"></script>
<!-- include spec files here... -->
<script type="text/javascript" src="UserControllerTest.js"></script>
</head>
<body>
</body>
</html>
and my main.js file used to load the requirejs dependencies is :
(function() {
require.config({
baseUrl: "../www/scripts",
// alias libraries paths
paths: {
'angular': '../libs/angular',
'angular-route': '../libs/angular-route',
'angular-animate':'../libs/angular-animate',
'angular-mocks':'../libs/angular-mocks',
'angularAMD': '../libs/angularAMD.min',
'Framework7':'../libs/framework7',
'UserController':'controller/UserCtrl',
'WebCallManager':'services/WebCallManager'
},
// Add angular modules that does not support AMD out of the box, put it in a shim
shim: {
'angularAMD': ['angular'],
'angular-route': ['angular'],
'angular-animate':['angular'],
'angular-mocks':['angular'],
'Framework7':{exports: 'Framework7'}
},
//kick start application
deps: ['app']
});
require(['Framework7'], function(Framework7) {
f7 = new Framework7({
modalTitle: 'Seed App',
swipePanel: 'left',
animateNavBackIcon: true
});
return {
f7: f7
};
});
})();
I have also given the entire source for my seed project here. I would much appreciate it if anyone could help me out.
You should include all the provider and services used in your controller to avoid this error
describe('Controller:UserController', function () {
var scope,controller,webcallService,$location;
beforeEach(module('app'));
beforeEach(inject(function ($controller,$rootScope,$injector,_webcallService_) {
scope = $rootScope.$new();
webcallService=_webcallService_;
$location=$injector.get('$location');
controller = $controller('UserController', { '$scope': scope });
}));
it('checks the troller name', function () {
expect(scope.name).toBe('Superhero');
});
});
The issue you are probably experiencing is that your test code runs before require+angular finishes initializing. You should write your testcode to take your use of requirejs and angularjs into account.
This will probably mean configuring your tests using require/define just like the rest of your code, and modifying the runner accordingly.
A possible solution would be a setup like the one proposed in the accepted answer here: Getting requirejs to work with Jasmine
UPDATE: also make sure to check this Does Jasmine 2.0 really not work with require.js? That basically tells you that without modifying the jasmine boot.js there is no way to postpone jasmine 2's initialization until after require is done.
Try this way:
describe('Controller:UserController', function () {
var scope,controller;
beforeEach(module('app'));
beforeEach(inject(function ($controller,$rootScope) {
scope = $rootScope.$new();
controller = $controller('UserController', { '$scope': scope });
}));
it('checks the troller name', function () {
expect(scope.name).toBe('Superhero');
});
});
I have some unit tests online with Jasmine 2.0, you may want to take a look a the code. For example this one: http://vtortola.github.io/ng-terminal-emulator/tests/spec/vtortola.ng-terminal.spec.js
I am guessing your app.js is never included.
Guessing it should be added below this:
<!-- include source files here... -->
<script data-main="main" src="framework/lib/require.js"></script>

AngularJS ui-router template does not loading

I'm new to AngularJS. I've following egghead.io I've set up a controller and model to retrieve message from input component and display it. I'm using ui-router.
Here's my index.html
<!DOCTYPE html>
<html ng-app="app">
<head lang="en">
<meta charset="UTF-8">
<title> </title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
<script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ui-view=""></div>
</body>
</html>
Here's my app.js
angular.module('app',["ui.router"])
.config([function($stateProvider) {
$stateProvider
.state('index', {
url:"",
templateUrl:"templates/first.html",
controller:"FirstCtr as first"
});
});
.controller("FirstCtr", function FirstCtr() {
var first = this;
first.greeting = "First";
});
Here's my templates/first.html
<input type="text" ng-model="first.greeting"/>
<div ng-class="first.greeting">
{{first.greeting}} {{"World"}}
</div>
After I go to http://localhost:8080, it was blank and throw this error
Please give me some suggestions.
Your state definition should be be declared controller alias in controllerAs option of state, with it you need to remove the semicolon from config block end.
Also you need to inject $stateProvider dependency properly to avoid error.
Code
angular.module('app', ["ui.router"])
//missed `'$stateProvider'` dependency here
.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('index', {
url: "",
templateUrl: "templates/first.html",
controller: "FirstCtr",
controllerAs: "first"
});
}]) //remove semicolon from here as you are appending app in chain
.controller("FirstCtr", function FirstCtr() {
var first = this;
first.greeting = "First";
});
Working Plunkr

Categories

Resources