Another way to inject in Angular - angularjs

I have a template and I'm changing the way to Inject dipendecies. It has the 'classic' way to inject. I want to replace it with the compact form. I can't do these line of code. I've tried but I can't understand the struscture. Because I am accustomed in the other form. Can somebody help me?
(function() {
'use strict';
angular.module('app.data')
.factory('postResource', postResource)
.factory('postsUtils', postsUtils);
postResource.$inject = ['$resource'];
function postResource($resource) {
return $resource('/api/posts/:id', {id: '#id'}, {
update: {
method: 'PUT'
}
});
}
postsUtils.$inject = ['postResource'];
function postsUtils(postResource) {
function postsDuringInterval(posts, days) {
var today = new Date();
var interval = 86400000 * days;
var postsDuringInterval = [];
posts.forEach(function(post) {
var postDate = new Date(post.date);
today - postDate < interval && postsDuringInterval.push(post);
});
return postsDuringInterval;
}
function recent(posts, postsNum) {
posts.sort(function(a, b) {
if (a.date < b.date) return 1;
else if (a.date == b.date) return 0;
else return -1;
});
return posts.slice(0, postsNum || 1);
}
function lastEdited(posts) {
var lastEdited = posts[0];
posts.forEach(function(post) {
lastEdited = lastEdited.date < post.date ? lastEdited : post;
});
return lastEdited;
}
return {
postsDuringInterval: postsDuringInterval,
lastEdited: lastEdited,
recent: recent
}
}
})();

Here is an example of how you would inject dependencies.
var app = angular.module('myApp',
['ngRoute', 'ngSanitize', 'ui.bootstrap', 'angular-flexslider',
'ng-backstretch', 'angular-parallax', 'fitVids', 'wu.masonry', 'timer',
'uiGmapgoogle-maps', 'ngProgress']);
An example of a controller that has a service injected into it.
app.controller('ContactController',['$scope','contactService',
function($scope, contactService) {
var self = this;
self.contact = {id:null, name:"",lastName:"",email:"",subject:"",message:""};
this.submit = function(){
contactService.submit(self.contact);
self.contact = {id:null, name:"",lastName:"",email:"",subject:"",message:""};
};
}]);
The factory:
app.factory('contactService',['$http','$q', function($http,$q){
return {
submit: function (contact) {
return $http.post('/sendForm/', contact)
.then(
function (response) {
return response;
},
function (errResponse) {
console.error("Error while submitting form" + errResponse);
return $q.reject(errResponse);
}
)
}
}
}]);
I think this is the way you were referring too. Hope this helps.

Related

$compile is not compiling angular template in jasmine after upgrading the angular version from 1.6 to 1.8 - unit testing

We have a code like this which was working well before. But started to fail post version upgrade from angular 1.6 to 1.8.
Looks like it needs some changes in source code but unable to identify the spot. This is happening due to the version upgrade.
Please help me to fix this unit tests. All our tests are failing.
(function (angular, moment, TimeShift) {
'use strict';
describe('references', function() {
var NORMAL_MAIL = {
'projectId': 1234
};
var BIM_UI_INTEGRATION = {
bimModuleKey: "BIM"
};
function setCurrentTime(zoneOffset, dateUTC) {
TimeShift.setTimezoneOffset(zoneOffset);
TimeShift.setTime(new Date(dateUTC).getTime());
}
beforeEach(module('directiveModule'));
beforeEach(function() {
window.Date = TimeShift.Date;
test.mocks.registeri18nFilter();
});
afterEach(function () {
window.Date = TimeShift.OriginalDate;
});
beforeEach(inject(function($rootScope, $compile) {
this.$rootScope = $rootScope;
this.$compile = $compile;
}));
beforeEach(function() {
setCurrentTime(-660, 0);
var element = angular.element('<references></references>');
this.element = this.$compile(element)(this.$rootScope.$new());
});
describe('no model references', function() {
it('should not display anything', function() {
this.$rootScope.mail = NORMAL_MAIL;
this.$rootScope.bimUiIntegration = BIM_UI_INTEGRATION;
this.$rootScope.isPreviewingFromEditMail = false;
this.$rootScope.$digest();
expect(this.element.find('header').length).toBe(0);
});
});
});
})(window.angular, window.moment, window.TimeShift);
And our source code is here.
(function(angular) {
angular
.module('directiveModule')
.component('references', {
templateUrl: 'mail/view/directives/mailModelsReferences/references.tpl.html',
controller: referencesController,
controllerAs: 'vm',
bindings: {
mail: '<',
bimUiIntegration: '<',
isPreviewingFromEditMail: '='
}
});
ReferencesController.$inject = ['$filter'];
function ReferencesController($filter) {
const vm = this;
let i18n = $filter('i18n');
vm.hasModelReferences = hasModelReferences;
vm.toDateString = toDateString;
vm.getBimModuleName = getBimModuleName;
if (hasModelReferences()) {
vm.model = vm.mail.models.model;
vm.viewpoint = vm.mail.models.viewpoint;
}
function hasModelReferences() {
let models = vm.mail ? vm.mail.models : vm.mail;
return models && (models.model || models.viewpoint);
}
function toDateString(dateField) {
if (dateField && dateField.value) {
let fieldValue = dateField.value;
let momentVal;
if (angular.isArray(fieldValue)) {
momentVal = window.moment(`${fieldValue[0]}-${fieldValue[1]}-${fieldValue[2]}`, 'YYYY-M-D');
} else {
momentVal = window.moment(fieldValue);
}
if (momentVal && momentVal.isValid()) {
return momentVal.format('LL');
}
}
return "";
}
function getBimModuleName() {
return i18n(vm.bimUiIntegration.bimModuleKey);
}
}
})(window.angular);

AngularJS paging

I made AngularJS pagination with spring mvc It works well ,but the application get a large amount of data from database so the application is very slow when I get first page because it get all records,Can anyone help me to solve this problem?I want to get subset of data from database depending on angularJS pagination
Spring mvc Controlller
#RequestMapping(value = "/rest/contacts",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public List<Contact> getAll() {
return contactRepository.findAll();
}
AngularJS Service
pagingpocApp.factory('Contact', function ($resource) {
return $resource('app/rest/contacts/:id', {}, {
'query': { method: 'GET', isArray: true},
'get': { method: 'GET'}
});
});
AngularJS Controller
pagingpocApp.controller('ContactController', function ($scope, $filter,resolvedContact, Contact, resolvedRole) {
$scope.contacts = resolvedContact;
var sortingOrder = 'firstName';
$scope.sortingOrder = sortingOrder;
$scope.reverse = false;
$scope.filteredItems = [];
$scope.groupedItems = [];
$scope.itemsPerPage = 10;
$scope.pagedItems = [];
$scope.currentPage = 0;
var searchMatch = function (haystack, needle) {
if (!needle) {
return true;
}
return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
};
// init the filtered items
$scope.search = function () {
$scope.filteredItems = $filter('filter')($scope.contacts, function (item) {
for(var attr in item) {
if (searchMatch(item[attr], $scope.query))
return true;
}
return false;
});
// take care of the sorting order
if ($scope.sortingOrder !== '') {
$scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sortingOrder, $scope.reverse);
}
$scope.currentPage = 0;
// now group by pages
$scope.groupToPages();
};
// calculate page in place
$scope.groupToPages = function () {
$scope.pagedItems = [];
for (var i = 0; i < $scope.filteredItems.length; i++) {
if (i % $scope.itemsPerPage === 0) {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [ $scope.filteredItems[i] ];
} else {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
}
}
};
$scope.range = function (start, end) {
var ret = [];
if (!end) {
end = start;
start = 0;
}
for (var i = start; i < end; i++) {
ret.push(i);
}
return ret;
};
$scope.prevPage = function () {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.nextPage = function () {
if ($scope.currentPage < $scope.pagedItems.length - 1) {
$scope.currentPage++;
}
};
$scope.setPage = function () {
$scope.currentPage = this.n;
};
// functions have been describe process the data for display
$scope.search();
// change sorting order
$scope.sort_by = function(newSortingOrder) {
if ($scope.sortingOrder == newSortingOrder)
$scope.reverse = !$scope.reverse;
$scope.sortingOrder = newSortingOrder;
// icon setup
$('th i').each(function(){
// icon reset
$(this).removeClass().addClass('icon-sort');
});
if ($scope.reverse)
$('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-up');
else
$('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-down');
};
});
One quick option would be to create a get method on your API that only returns a subset of the data, maybe only 25 contacts at a time, or a page or two worth of data. Then you could create a service in angular that makes that get call every 3 seconds or so to get the next 25 contacts. A sort of lazy loading technique.
Ben Nadel does a great job in this article of outlining how his company handles large sets of images being loaded to a page using a lazy loading technique. Reading through his example could give you a nice starting point.
Edit: I'm also going to recommend you refer to this solution for an answer slightly more on point to what you're looking to achieve. He recommends pushing data to your controller as soon as it's found:
function MyCtrl($scope, $timeout, $q) {
var fetchOne = function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve([random(), random() + 100, random() + 200]);
}, random() * 5000);
return deferred.promise;
};
$scope.scans = [];
for (var i = 0; i < 2; i++) {
fetchOne().then(function(items) {
angular.forEach(items, function(item) {
$scope.scans.push(item);
});
});
};
}

angular and prettyphoto url from blobstorage

Prettyphoto stopped working after I changed the href url to an angular tag: {{something.uri}}
Javascript:
jQuery(".prettyphoto").prettyPhoto({
theme: 'pp_default',
overlay_gallery: false,
social_tools: false,
deeplinking: false,
theme: 'dark_rounded'
});
$("a[rel^='prettyPhoto']").prettyPhoto();
HTML:
<div ng-show="model.fileList" ng-repeat="fileList in model.fileList">
<a ng-href="{{fileList.uri}}" class="prettyphoto">
<img ng-src="{{fileList.uri}}" class="img-thumbnail" width="100" alt="" />
</a>
</div>
Angular scope from blobstorage:
fileList: [
{
parentContainerName: documents
uri: https://xxxxxx.blob.core.windows.net/documents/20140702.jpg
filename: 20140702.jpg
fileLengthKilobytes: 293
}
]
app.factory('storageService',
["$http", "$resource", "$q",
function ($http, $resource, $q) {
//resource to get summaryRoles
var resourceStorageManager = $resource('/api/storageManager/:id', { id: '#id' });
return {
getFileList: function () {
var deferred = $q.defer();
resourceStorageManager.query(, function (data) {
deferred.resolve(data);
}, function (status) {
deferred.reject(status);
}
);
return deferred.promise;
}
};
}]);
app.controller('startController', ['$scope', '$http', '$timeout', '$upload', 'storageService', 'settings',
function startController($scope, $http, $timeout, $upload, storageService, settings, profileRepository, notificationFactory, $q) {
$http.defaults.headers.common = { 'RequestVerificationToken': $scope.__RequestVerificationToken };
$scope.model = {};
$scope.model.fileList = null;
$scope.model.roundProgressData = {
label: 0,
percentage: 0.0
};
$scope.$on("pic_profileone_main", function (event, profileExtInfo1) {
$scope.changeprofilepicmodel1 = angular.copy(profileExtInfo1);
refreshServerFileList();
});
$scope.$on("pic_profiletwo_main", function (event, profileExtInfo2) {
$scope.changeprofilepicmodel2 = angular.copy(profileExtInfo2);
refreshServerFileList2();
});
$scope.onFileSelect = function ($files, callernumber, foldername, blobtype) {
if (callernumber == 1) {
$scope.blobModel = angular.copy($scope.changeprofilepicmodel1);
$scope.blobModel.folderName = foldername;
$scope.blobModel.blobTypeCode = blobtype;
} else if (callernumber == 2) {
$scope.blobModel = angular.copy($scope.changeprofilepicmodel2);
$scope.blobModel.folderName = foldername;
$scope.blobModel.blobTypeCode = blobtype;
}
$scope.selectedFiles = [];
$scope.model.progress = 0;
// Assuming there's more than one file being uploaded (we only have one)
// cancel all the uploads
if ($scope.upload && $scope.upload.length > 0) {
for (var i = 0; i < $scope.upload.length; i++) {
if ($scope.upload[i] != null) {
$scope.upload[i].abort();
}
}
}
$scope.upload = [];
$scope.uploadResult = [];
$scope.selectedFiles = $files;
// Ok, we only want one file to be uploaded
// let's take the first one and that's all
var $file = $files[0];
// Only first element, single file upload
(function (index) {
$scope.upload[index] = $upload.upload({
url: settings.constants.uploadURL,
headers: { 'myHeaderKey': 'myHeaderVal' },
method: 'POST',
data: $scope.blobModel,
file: $file,
fileFormDataName: 'myFile'
}).then(function (response) {
var look = response;
$scope.model.progress = 100;
// you could here set the model progress to 100 (when we reach this point we now that the file has been stored in azure storage)
$scope.uploadResult.push(response.data);
$scope.$emit('ClearUploadPics');
refreshServerFileList();
}, null, function (evt) {
// Another option is to stop here upadting the progress when it reaches 90%
// and update to 100% once the file has been already stored in azure storage
$scope.model.progress = parseInt(100.0 * evt.loaded / evt.total);
$scope.model.roundProgressData.label = $scope.model.progress + "%";
$scope.model.roundProgressData.percentage = ($scope.model.progress / 100);
});
})(0);
};
function refreshServerFileList() {
storageService.getFileList().then(function (data) {
$scope.model.fileList = data;
}
);
}
function initialize() {
refreshServerFileList();
}
initialize();
$scope.$on("ClearProgressBar", function (event) {
$scope.selectedFiles = null;
});
}]);
I hope this is okay and more readable.

angular, try to display object in ng-repeat fails

i'm writing an mobile application in javascript with angularJS and ionicframework (last beta v.11), i create dinamically an object and want to display all objects inside in a ng-repeat. Why nr-repeat don't display anything?
This is screen from my object:
I use this code for put values in scope:
$scope.distanceSuppliers = myCar;
And this is the code in html:
<ion-item ng-repeat="(id, supplier) in distanceSuppliers">
<div class="items item-button-right" ng-click="openDetails(id)">
{{supplier.name}}<br />
{{supplier.address}}<br />
</div>
</ion-item>
This is my complete code for JS:
.controller('suppliers', function($scope, cw_db, $ionicPopup, $ionicActionSheet, appdelegate, $rootScope, $firebase, $location, $ionicLoading, cw_position) {
$ionicLoading.show({
template: 'Updating data..'
});
var geocoder;
var tot = 0;
var done = 0;
geocoder = new google.maps.Geocoder();
cw_db.getData(cw_db.getSuppliers(), "", function(suppliers) {
cw_position.getPosition(function (error, position) {
suppliers.on('value', function(supp) {
$scope.distanceSuppliers = {};
tot = 0;
done = 0;
supp.forEach(function(childSnapshot) {
tot++;
var childData = childSnapshot.val();
if (childData.address) {
calculateDistance(childData, position.coords.latitude, position.coords.longitude);
}
});
});
$ionicLoading.hide();
});
});
function calculateDistance(childData, usrLat, usrLon) {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [new google.maps.LatLng(usrLat, usrLon)],
destinations: [childData.address],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, function(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
done++;
var results = response.rows[0].elements;
childData.distance = results[0].distance.value;
$scope.distanceSuppliers.push(childData);
if (done == tot) {
console.log($scope.distanceSuppliers);
}
}
});
}
$scope.openDetails = function(index) {
//appdelegate.setCallId(index);
//$location.path("/app/supplierDetails");
}
})
what's wrong?
Not sure, but I believe you have a data binding update problem.
Try using the $timeout to force the render:
w_position.getPosition(function (error, position) {
$timeout(function() {
suppliers.on('value', function(supp) {
$scope.distanceSuppliers = {};
tot = 0;
done = 0;
supp.forEach(function(childSnapshot) {
tot++;
var childData = childSnapshot.val();
if (childData.address) {
calculateDistance(childData, position.coords.latitude, position.coords.longitude);
}
});
});
$ionicLoading.hide();
});
});
And don't forget to add the $timeout parameter to the controller:
.controller('suppliers', function($scope, ...<other parameters here>..., $timeout) {
I found the problem! Fix using $scope.$apply();
The problem was that i was writing in a different $scope using this code:
cw_position.getPosition(function (error, position) {
suppliers.on('value', function(supp) {
tot = 0;
done = 0;
supp.forEach(function(childSnapshot) {
tot++;
var childData = childSnapshot.val();
if (childData.address) {
calculateDistance(childData, position.coords.latitude, position.coords.longitude);
}
});
});
$ionicLoading.hide();
});
where cw_position.getPosition call a js with this code:
angular.module('cw_position', [])
.service('cw_position', function() {
this.getPosition = function(callback) {
navigator.geolocation.getCurrentPosition(
function (position) {
return callback(null, position);
},
function(error) {
return callback(error, null);
}
);
}
// Built google maps map option
//
this.getGoogleMapOptions = function (lat, lon, zoom, type) {
if (type == null) {
type = google.maps.MapTypeId.ROADMAP;
}
var mapOptions = {
center: new google.maps.LatLng(lat, lon),
zoom: zoom,
mapTypeId: type
};
return mapOptions;
}
});
navigator.geolocation.getCurrentPosition causes the 'problem'
Thx to all for your help

AngularJS Chart Directive - Data loaded in async service not updating chart

I am having one chart directive created, and I am bootstrpping the app after loading google api. In following code, a simple data table is working fine. But when I load data from server in async manner, chart is not being displayed.
Controller
'use strict';
myNetaInfoApp.controller('allCandidatesController', [
'$scope','allCandidates2009Svc', '$timeout',
function ($scope, allCandidates2009Svc, $timeout) {
$scope.data1 = {};
$scope.data1.dataTable = new google.visualization.DataTable();
$scope.data1.dataTable.addColumn("string", "Party");
$scope.data1.dataTable.addColumn("number", "qty");
$scope.data1.dataTable.title = "ASDF";
$timeout( function (oldval, newval) {
allCandidates2009Svc.GetPartyCriminalCount().then(function(netasParty) {
var i = 0;
for (var key in netasParty) {
$scope.data1.dataTable.addRow([key.toString(), netasParty[key]]);
i++;
if (i > 20) break;
}
});
});
$scope.dataAll = $scope.data1;
//sample data
$scope.data2 = {};
$scope.data2.dataTable = new google.visualization.DataTable();
$scope.data2.dataTable.addColumn("string", "Name");
$scope.data2.dataTable.addColumn("number", "Qty");
$scope.data2.dataTable.addRow(["Test", 1]);
$scope.data2.dataTable.addRow(["Test2", 2]);
$scope.data2.dataTable.addRow(["Test3", 3]);
}
]);
Service
'use strict';
myNetaInfoApp.factory('allCandidates2009Svc', ['$http', '$q',
function ($http, $q) {
var netas;
return {
GetPartyCriminalCount: function () {
var deferred = $q.defer();
$http.get('../../data/AllCandidates2009.json')
.then(function (res) {
netas = res;
if (netas) {
var finalObj = {};
_.each(netas.data, function(neta) {
finalObj[neta.pty] = finalObj[neta.pty] ? finalObj[neta.pty] + 1 : 1;
});
deferred.resolve(finalObj);
}
});
return deferred.promise;
}
};
}]);
Directive
"use strict";
var googleChart = googleChart || angular.module("googleChart", []);
googleChart.directive("googleChart", function () {
return {
restrict: "A",
link: function ($scope, $elem, $attr) {
var dt = $scope[$attr.ngModel].dataTable;
var options = {};
if ($scope[$attr.ngModel].title)
options.title = $scope[$attr.ngModel].title;
var googleChart = new google.visualization[$attr.googleChart]($elem[0]);
$scope.$watch($attr.ngModel, function (oldval, newval) {
googleChart.draw(dt, options);
});
}
};
});
HTML
<div ng-controller="allCandidatesController">
<div class="col-lg-6">
<h2>Parties and Candidates with Criminal Charges</h2>
<div google-chart="PieChart" ng-model="dataAll" class="bigGraph"></div>
<!--<p><a class="btn btn-primary" href="#" role="button">View details ยป</a></p>-->
</div>
<div class="col-lg-6">
<h2>Heading</h2>
<div google-chart="BarChart" ng-model="data2" class="bigGraph"></div>
</div>
</div>
I think you need to wrap your function body in allCandidates2009Svc factory with scope.$apply(). But the return deferred.resolve() will be outside scope.$apply().
function asyncGreet(name) {
var deferred = $q.defer();
setTimeout(function() {
// since this fn executes async in a future turn of the event loop, we need to wrap
// our code into an $apply call so that the model changes are properly observed.
scope.$apply(function() {
deferred.notify('About to greet ' + name + '.');
if (okToGreet(name)) {
deferred.resolve('Hello, ' + name + '!');
} else {
deferred.reject('Greeting ' + name + ' is not allowed.');
}
});
}, 1000);
return deferred.promise;
}
Read the docs here
http://docs.angularjs.org/api/ng.$q

Resources