I've just started using Angular alongside RequireJs and so far I have created a structure that looks like this:
app.js
app.core.js
app.controllers.js
app.services.js
The core module is where I hinge dependencies and pull in the services and controller modules, like this for example:
(function () {
var dependancies = ['angular'];
define(dependancies, function (angular) {
return angular.module('app.services', [])
.factory('VehicleService', ['$injector', function ($injector) {
var stub = {};
require(['../Angular/Services/VehicleService'], function (VehicleService) {
angular.extend(stub, $injector.invoke(VehicleService));
});
return stub;
}]);
});
})();
And each service is created in its own file like so:
(function () {
define(function () {
return ['$http', function ($http) {
return {
getAllMakes: function () {
return $http.get('/Api/RegisteredVehicle/GetAllMakes')
.success(function (response) {
return {
vehicleName: response
}
});
}
};
}];
});
})();
How can I now use $stateprovider.state.resolve and get my service instantiated correctly?
.state('quote', {
url: '/quote',
templateUrl: '/Sales/Dashboard/CreateQuoteVehicle',
controller: 'QuoteProposalCtrl as vm',
resolve: {
vehicleInfo: function () {
var stub = {};
require(['../Angular/Services/VehicleService'], function (VehicleService) {
angular.extend(stub, $injector.invoke(VehicleService));
});
return stub;
}
}
})
On your core angular module, inject $stateProvider, then put in the states. It should pull in the rest of your dependancies. This should then be loaded as the main starting requirejs file.
(function () {
var dependancies = ['angular', 'app.core', 'app.controllers', 'app.services'];
define(dependancies, function (angular) {
var app = angular.module('myApp', ['app.core', 'app.controllers', 'app.services']);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('quote', {
url: '/quote',
templateUrl: '/Sales/Dashboard/CreateQuoteVehicle',
controller: 'QuoteProposalCtrl as vm',
resolve: {
vehicleInfo: function () {
var stub = {};
require(['../Angular/Services/VehicleService'], function (VehicleService) {
angular.extend(stub, $injector.invoke(VehicleService));
});
return stub;
}
}
})
});
return app;
})();
Depending on your setup you'd be loading the app something like:
<script data-main="scripts/app" src="scripts/require.js"></script>
One thing, im not sure you need this require, since it should already be loaded with the app.services dependancy.
var stub = {};
require(['../Angular/Services/VehicleService'], function (VehicleService) {
angular.extend(stub, $injector.invoke(VehicleService));
});
return stub;
Related
This is my service:
(function () {
'use strict';
angular
.module('app')
.service('ClientsService', Service);
function Service($http) {
function getClients() {
$http.get('app/client/clients.json')
.then(function(res){
return res.data;
});
}
return {
getClients: getClients,
};
}
})();
If I a console log inside then I can obtain the clients from the json file.
Then I want to use the service in my component:
(function () {
'use strict';
var module = angular.module('app');
module.component("client", {
templateUrl: "app/client/client.html",
controllerAs: "model",
controller: function (ClientsService) {
var model = this;
model.clients = ClientsService.getClients();
console.log(model.clients)
}
});
})();
But the log says me: undefined.
How can I fix it?
You'll need minor refactoring for this to work.
(function () {
'use strict';
angular
.module('app')
.service('ClientsService', Service);
function Service($http) {
function getClients() {
//Notice the return here? we're returning a promise.
return $http.get('app/client/clients.json')
.then(function(res){
return res.data;
});
}
return {
getClients: getClients,
};
}
})();
(function () {
'use strict';
var module = angular.module('app');
module.component("client", {
templateUrl: "app/client/client.html",
controllerAs: "model",
controller: function (ClientsService) {
var model = this;
//getClients() now returns a promise that is resolved
//when the client list is loaded
ClientsService.getClients().then(function(clients){
model.clients = clients;
console.log(model.clients);
});
}
});
})();
It is because, the http request has not been completed. You will have data only after completion of http request. You can try following code. Also return http promise from the service.
module.component("client", {
templateUrl: "app/client/client.html",
controllerAs: "model",
controller: function (ClientsService) {
var model = this;
ClientsService.getClients().then(function(clients){
model.clients = clients;
console.log(model.clients)
})
}
});
Change Service like this:
(function () {
'use strict';
angular
.module('app')
.service('ClientsService', Service);
function Service($http) {
function getClients() {
return $http.get('app/client/clients.json')
.then(function(res){
return res.data;
});
}
return {
getClients: getClients,
};
}
})();
I have downloaded AngularJS - ToDo Application from http://www.tutorialspoint.com/angularjs/ and trying to implement same as it is. As I am new in AngularJS, I am stuck somewhere.
In this app AngularJS service " localStorage" is included by object name 'store' in controller. But when I am trying to do this it couldn't work for me.
mainApp = angular.module('mainApp', ['ngRoute']);
mainApp.config(function($routeProvider) {
'use strict';
var routeConfig = {
templateUrl: 'template/add_todo.html',
controller: 'addToDoController',
resolve: {
store: function(todoStorage) {
// Get the correct module (API or localStorage).
return todoStorage.then(function(module) {
return module;
});
}
}
};
$routeProvider
.when('/', routeConfig)
.otherwise({
redirectTo: '/'
});
});
mainApp.factory('todoStorage', function($http, $injector) {
'use strict';
// Detect if an API backend is present. If so, return the API module, else
// hand off the localStorage adapter
return $http.get('/api')
.then(function() {
//return $injector.get('api');
}, function() {
var store = $injector.get('localStorage');
return store;
});
})
mainApp.factory('localStorage', function($q) {
'use strict';
var store = {
todos: [],
insert: function(todo) {
store.todos.push(todo);
console.log(store.todos);
return store.todos;
}
};
return store;
});
mainApp.controller('addToDoController', function($scope, store) {
'use strict';
$scope.addTodo = function() {
var newTodo = {
title: $scope.newTodo.trim(),
completed: false
};
$scope.saving = false;
store.insert(newTodo)
$scope.newTodo = '';
}
});
I want to inject a service into app.config any idea please ?I want to inject a service into app.config any idea please ?I want to inject a service into app.config any idea please ?
app.js
'use strict';
angular.module('crud', [
'ngRoute',
'angular-jwt',
'ngSails',
'ngMessages',
'ngResource'
])
.config(function ($httpProvider,$routeProvider, $locationProvider,$sailsProvider,jwtInterceptorProvider,User) {
//$httpProvider.interceptors.push('jwtInterceptor');
//console.log($sailsProvider);
$routeProvider
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
});
Serviceuser.js
'use strict';
angular.module('crud').service('User', function ($sails) {
//console.log($sails);
return {
signup: function (data) {
return $sails.post('/api/user',data);
}
}
});
Here you go straight from the docs:
Registering a Service with $provide
You can also register services via the $provide service inside of a module 's config function:
angular
.module('myModule', [])
.config(['$provide ',
function($provide) {
$provide.factory('serviceId ', function() {
var shinyNewServiceInstance;
// factory function body that constructs shinyNewServiceInstance
return shinyNewServiceInstance;
});
}
]);
This technique is often used in unit tests to mock out a service'
s dependencies.
Hope this helps.
(function() {
'use strict';
angular
.module('example.app', [])
.config(['$provide',
function($provide) {
$provide.factory('serviceId', function() {
var shinyNewServiceInstance;
// factory function body that constructs shinyNewServiceInstance
return shinyNewServiceInstance;
});
}
])
.controller('ExampleController', ExampleController)
.service('exampleService', exampleService);
exampleService.$inject = ['$http'];
function ExampleController(exampleService) {
var vm = this;
vm.update = function(person, index) {
exampleService.updatePeople(person).then(function(response) {
vm.persons = response;
}, function(reason) {
console.log(reason);
});
};
}
// good practice to use uppercase variable for URL, to denote constant.
//this part should be done in a service
function exampleService($http) {
var URL = 'https://beta.test.com/auth/authenticate/',
data = {},
service = {
updatePeople: updatePeople
};
return service;
function updatePeople(person) {
//person would be update of person.
return $http
.post(URL, person)
.then(function(response) {
return response.data;
}, function(response) {
return response;
});
}
}
})();
you can use like:
angular.module('app', ["ui.router"])
.config(function config ($stateProvider){
$stateProvider.state("index", {
url:"",
controller: "FirstCtrl as first",
templateUrl: "first.html"
})
.state("second", {
url:"/second",
controller:"SecondCtrl as second",
templateuRL:"second.html"
})
})
here is the full working example with plunker
I can lazy load a controller by doing the following,
Step1: Add an additional config...
rootModule.config([
"$controllerProvider", function($controllerProvider) {
rootModule.registerController = $controllerProvider.register;
}
]);
Step2: Define the controller against the registerController defined in step 1
angular.module("rootModule").registerController("authController",
function ($scope, $location, $rootScope, authService) {
$scope.userName = "";
$scope.userPwd = "";
$scope.authenticate = function ()...
$scope.testFunction = function ()...
});
Step3: load the controller during routing by doing this,
rootModule
.config([
'$routeProvider',
function ($routeProvider) {
$routeProvider.when('/',
{
templateUrl: 'templates/Login.html',
resolve: {
load: ["$q", function($q) {
var defered = $q.defer();
require(["Controllers/authController"], function() {
defered.resolve();
});
return defered.promise;
}]
}
}).
Now, the problem is I have a service called "authService", which I would like to lazy load, how to do it? Here is the service...
define(function() {
angular.module("rootModule").service("authService", function ($http) {
return {
/////Something code here//////
});
});
It was very simple in the end, thanks to this great blog written by Dan Wahlin.
To load a service in run time according to the routing, I had to do this...
Step 1: Get a reference to $provide.service() method in my rootModule's (module which contains the routing info) config...
rootModule.config(["$controllerProvider","$provide",
"$controllerProvider", "$filterProvider","$compileProvider", function ($controllerProvider, $provide) {
rootModule.registerController = $controllerProvider.register; //for controllers
rootModule.registerService = $provide.service; //for services
rootModule.registerFilter = $filterProvider.register; //for filters
rootModule.registerDirective = $compileProvider.directive; //for directives
rootModule.registerFactory = $provide.factory; //for factory
}
]);
Step 2: Register the service to be loaded dynamically
define(function() {
angular.module("rootModule").registerService("reviewReportsService", function () {
return {
sampleData: "This is some sample data"
}
});
});
Step 3: Resolve the service script file, to load when the respective route is loaded
when('/ReviewAndSubmit',
{
controller: "reviewAndSubmitController",
templateUrl: "templates/ReviewAndSubmit.html",
resolve: {
load: ["$q", function ($q) {
var defered = $q.defer();
require(["Controllers/reviewAndSubmitController"], function () {
defered.resolve();
});
require(["Services/reviewReportsService"], function () {
defered.resolve();
});
return defered.promise;
}]
}
})
Hope this helps someone....
I have integrated requirejs with my angular app.
But while loading app, it gives me an error 'Argument 'appCtrl' is not a function, got undefined'
Here is my controller code :
define(['Angular'], function (angular) {
function appCtrl($scope, pathServices) {
alert('sa');
}
function homeCtrl($scope, brandService) {
console.log('dfd');
}
});
And along with this, it gives error for 'unknown provider pathServices'
Service code is :
serviceConfig.js
define([
'Angular',
'common/Services/services',
'current/js/services'
], function(angular, commonServices, loacalStorageServices, currentServices) {
"use strict";
var services = {
commonServices : commonServices,
currentServices : currentServices,
};
var initialize = function (angModule) {
angular.forEach(services,function(service, name) {
angModule.service(name, service);
});
}
return {
initialize: initialize
};
});
common/services.js
define(['Angular'], function (angular) {
var app = angular.module('myApp.services', []);
app.factory('pathServices', function($http, $q, $rootScope) {
function pathServices() {
alert('as');
}
return new pathServices();
});
app.factory('anotherServices', function($http, $q, $rootScope) {
function anotherServices() {
alert('as');
}
return new anotherServices();
});
});
current/services.js
define(['Angular'], function(angular) {
var app = angular.module('myApp.services', []);
app.factory('brandsService', function() {
function brandsService() {
var autoCompleteData = [];
this.getSource = function() {
return autoCompleteData;
}
this.setSource = function(states) {
autoCompleteData = states;
}
}
return new brandsService();
});
});
in serviceConfig.js I have included 2 service files.. But the problem is, the last current/service.js file overwrites all files.. How can I include multiple service files ?
I am new to requirejs. How can I use controller function and services using requirejs ?
Can anyone help ?
You have to declare your functions in the global (window) namespace, or register them in your module with the moduleName.controller('controllerName',controllerFn)
So either
define(['Angular'], function (angular) {
window.appCtrl = function($scope, pathServices) {
alert('sa');
}
window.homeCtrl = function($scope, brandService) {
console.log('dfd');
}
});
or
define(['Angular'], function (angular) {
var module = angular.module('theModuleName');
module.controller('appCtrl', function($scope, pathServices) {
alert('sa');
});
module.controller('homeCtrl', function($scope, brandService) {
console.log('dfd');
}
});
should fix this error (I prefer the second approach).