how to inject service into controller using service object name? - angularjs

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 = '';
}
});

Related

Yet Another Asynchronous service returns Undefined

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,
};
}
})();

Inject service in app.config?

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

Angular + RequireJs + Ui.Router

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;

Lazy loading angular services using require.js

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....

Prevent multiple ajax calls when re-using a controller/factory

just starting out really with Angular and need some advice regarding preventing repeated ajax requests for the same data when re-using a controller with multiple view.
So I have say 6 views all referencing the same controller but different views
app.js
(function() {
var app = angular.module('myApp', ['ngRoute','ui.unique']);
app.config(function ($routeProvider) {
// Routes
$routeProvider
.when('/',
{
controller: 'SamplesController',
templateUrl: 'app/views/home.html'
})
.when('/view2/',
{
controller: 'SamplesController',
templateUrl: 'app/views/main.html'
})
.when('/view3/:rangeName',
{
controller: 'SamplesController',
templateUrl: 'app/views/samples.html'
})
.when('/view4/:rangeName',
{
controller: 'SamplesController',
templateUrl: 'app/views/samples.html'
})
.when('/view5/',
{
controller: 'SamplesController',
templateUrl: 'app/views/basket.html'
})
.when('/view6/',
{
controller: 'SamplesController',
templateUrl: 'app/views/lightbox.html'
})
.otherwise({ redirectTo: '/' });
});
}());
samplesController.js
(function() {
var SamplesController = function ($scope, SamplesFactory, appSettings, $routeParams) {
function init() {
// back function
$scope.$back = function() {
window.history.back();
};
// app settings
$scope.settings = appSettings;
// samples list
SamplesFactory.getSamples()
.success(function(data){
var returnSamples = [];
for (var i=0,len=data.length;i<len;i++) {
if (data[i].range === $routeParams.rangeName) {
returnSamples.push(data[i]);
}
}
$scope.samples = returnSamples;
})
.error(function(data, status, headers, config){
// return empty object
return {};
});
// variables for both ranges
$scope.rangeName = $routeParams.rangeName;
// click to change type
$scope.populate = function(type) {
$scope.attributeValue = type;
};
};
init();
};
SamplesController.$inject = ['$scope','SamplesFactory', 'appSettings', '$routeParams'];
angular.module('myApp').controller('SamplesController', SamplesController);
}());
samplesFactory.js
(function () {
var SamplesFactory = function ($http) {
var factory = {};
factory.getSamples = function() {
return $http.jsonp('http://www.website.com/app/index.php?callback=JSON_CALLBACK');
};
return factory;
};
SamplesFactory.$inject = ['$http'];
angular.module('myApp').factory('SamplesFactory', SamplesFactory);
}());
So with this - every time a new view is loaded the ajax request is made again - how would I re-purpose to have only a single request happen?
As always thanks in advance
Carl
UPDATE: Answer marked below but I also had success by changing the "cache" config item/property (whatever its called) to true in the jsonp request
return $http.jsonp('http://www.website.com/app/index.php?callback=JSON_CALLBACK',{cache: true});
You could change your factory in this way:
(function () {
var SamplesFactory = function ($http) {
var factory = {},
samples = $http.jsonp('http://www.website.com/app/index.php?callback=JSON_CALLBACK');
factory.getSamples = function() {
return samples;
};
return factory;
};
SamplesFactory.$inject = ['$http'];
angular.module('myApp').factory('SamplesFactory', SamplesFactory);
}());
Now getSamples() returns a promise that you should manage in your controllers.

Resources