I am trying to clean up a controller that has too many lines of code in it. In the controller below where you find a function called getProductDetails, I would like to move the filter to a factory or a service, but I am not sure how to do it.
'use strict';
(function () {
var userQuoteBuild = angular.module('priceApp');
userQuoteBuild.controller('quoteBuilderController', function ($scope, $http) {
// loads of controller logic here...
$scope.getProductDetails = function (item) {
$scope.listOfProductVariants = item.default_variant_attributes;
// TODO: put this in its own factory?
$scope.selectedProductAttributes = $scope.listOfAttributes.filter(function (item) {
var validated = false, i, length = $scope.listOfProductVariants.length;
for (i = 0; i < length; i++) {
if (item.name === $scope.listOfProductVariants[i]){
validated = true;
}
}
return validated;
});
};
});
(function () {
'use strict';
angular
.module('priceApp')
.factory('filterService', filterService);
function filterService() {
var service = {
getValidated: getValidated
}
return service;
function getValidated(list, variants) {
return list.filter(function (item) {
var validated = false, i, length = variants.length;
for (i = 0; i < length; i++) {
if (item.name === variants[i]) {
validated = true;
}
}
return validated;
});
}
}
})();
Simply inject this filterService to your controller and then use it as in example here:
$scope.selectedProductAttributes = filterService
.getValidated($scope.listOfAttributes,
$scope.listOfProductVariants)
I followed John Papa's AngularJS Style Guide. Make sure to choose a better name than filterService. : )
Check this:
userQuoteBuild.factory('myService', function() {
var service = {
getProductDetails: function(item) {
// your logic
return value;
}
}
return service;
});
Related
I currently put my constants on the $scope. I don't feel like this is the best way to do it as anyone can access the scope with their JS console.
What is the best method to define constants in Angular?
var app = angular.module('app', []);
app.controller('calculatorController', function($scope) {
$scope.values = [];
$scope.CONSTANTS = {
ERROR_MESSAGES: {
NOT_INTEGER: "One of the values input was not a number!"
}
};
$scope.add = function () {
var calculatedValue = 0;
for (var i = 0; i <= $scope.values; i++) {
if (typeof $scope.values[i] === 'string' || $scope.values[i] instanceof String) {
alert($scope.CONSTANTS.ERROR_MESSAGES.NOT_INTEGER);
}
calculatedValue += $scope.values[i];
}
return calculatedValue;
}
});
Just make it a variable within the controller callback (or a const if using TypeScript or ES2015+ JavaScript):
var app = angular.module('app', []);
app.controller('calculatorController', function($scope) {
var ERROR_MESSAGES = {
NOT_INTEGER: "One of the values input was not a number!"
};
$scope.values = [];
$scope.add = function () {
var calculatedValue = 0;
for (var i = 0; i <= $scope.values; i++) {
if (typeof $scope.values[i] === 'string' || $scope.values[i] instanceof String) {
alert(ERROR_MESSAGES.NOT_INTEGER);
}
calculatedValue += $scope.values[i];
}
return calculatedValue;
}
});
(Though that particular kind of constant should probably be loaded from somewhere...)
If you want all the constants at one place, another way is to declare constants as below .
var app = angular.module('app', []);
angular.module('AppName').constant('versionConstant', {
"versionNum":"1.22"
});
// And inject them in your controller
angular.module(AppName).controller(ControllerName, ['$scope','versionConstant',
function ($scope, versionConstant) {
var version=versionConstant.versionNum;
});
I created an application where I have controller and factory. I have an array inside of the factory where I want to push id of the element to this array. However, when I am trying to push element to array I got an error that
"favorites.push is not a function"
Below you can find my controller and factory. Thank you for reading:
Factory:
.factory('favoriteFactory',['$resource', 'baseURL','$localStorage', function ($resource, baseURL, $localStorage) {
var favFac = {};
var favorites = $localStorage.get('favorites', []);
favFac.addFavorites = function (index) {
for(var i=0; i<favorites.length; i++){
if(favorites[i].id == index)
return
}
favorites.push({id: index});
$localStorage.storeObject('favorites',favorites)
}
favFac.deleteFromFavorites = function (index) {
for (var i = 0; i < favorites.length; i++) {
if (favorites[i].id == index) {
favorites.splice(i, 1);
}
}
$localStorage.storeObject('favorites', favorites)
};
favFac.getFavorites = function () {
return $localStorage.getObject('favorites',[]);
};
return favFac
}])
Controller:
.controller('MenuController', ['$scope', 'menuFactory', 'favoriteFactory','baseURL', '$ionicListDelegate', 'dishes', '$localStorage',
function($scope, menuFactory,favoriteFactory, baseURL, $ionicListDelegate, dishes, $localStorage) {
$scope.baseURL = baseURL;
$scope.tab = 1;
$scope.filtText = '';
$scope.showDetails = false;
$scope.showMenu = true;
$scope.message = "Loading ...";
$scope.addFavorite = function (index) {
console.log("index:" +index);
favoriteFactory.addFavorites(index);
$ionicListDelegate.closeOptionButtons();
};
$scope.dishes = dishes;
$scope.select = function(setTab) {
$scope.tab = setTab;
if (setTab === 2) {
$scope.filtText = "appetizer";
}
else if (setTab === 3) {
$scope.filtText = "mains";
}
else if (setTab === 4) {
$scope.filtText = "dessert";
}
else {
$scope.filtText = "";
}
};
$scope.isSelected = function (checkTab) {
return ($scope.tab === checkTab);
};
$scope.toggleDetails = function() {
$scope.showDetails = !$scope.showDetails;
};
}])
I assume you are using ngStorage. The get method does not have a second parameter. Therefore, your attempt at returning a default value of [](empty array) is simply returning undefined and then you are attempting to push to undefined and not to an array.
The source code for ngStorage shows no second parameter for get:
https://github.com/gsklee/ngStorage/blob/master/ngStorage.js
So this line:
var favorites = $localStorage.get('favorites', []);
Should be this:
var favorites = $localStorage.get('favorites') || [];
I have a data in my commonservice and I want to use the data in my template and I will assign a rootscope and use it but it isn't working right now and I am not sure what's wrong can anyone please suggest help.
My js:
function addGoogleAddress(id, data, scope) {
var places = new google.maps.places.Autocomplete(document.getElementById(id));
google.maps.event.addListener(places, 'place_changed', function () {
var place = places.getPlace();
if (place && place.address_components) {
for (var i = 0; i < (place.address_components.length); i++) {
if (place.address_components[i].types[0] === 'locality') {
data.city.key = '1001';
data.city.name = place.address_components[i].long_name.toString();
} else if (place.address_components[i].types[0] === 'administrative_area_level_1') {
data.state.key = '1001';
data.state.name = place.address_components[i].long_name.toString();
} else if (place.address_components[i].types[0] === 'country') {
data.country.key = '1001';
data.country.name = place.address_components[i].long_name.toString();
}
}
}
});
$timeout(function () {
$('#' + id).removeAttr('placeholder');
}, 500);
$rootScope.data = data;
}
My controller:
console.log($rootScope.data)
Here i am getting undefined.
You can not broadcast data directly, you need to broadcast event and pass parameter like follows,
Note: I am assuming here you have injected dependency
$rootScope.$broadcast('eventName',data);
Then in controller like follows -
$scope.$on('eventName',function(event,data){
console.log('data---',data);
})
app.controller('ctrl1',['$scope','$rootScope',function($scope,$rootScope) {
$scope.xyz = $rootScope.xyz;
//console.log($scope.xyz); hey
}]);
app.run(function($rootScope){
$rootScope.xyz ="hey";
})
I have this controller:
(function () {
"use strict";
angular.module("workPlan").controller("genericFilterDataController", ["$scope", genericFilterDataController]);
function genericFilterDataController($scope) {
$scope.data = ['bla1', 'bla2', 'bla3'];
$scope.foo = function () {
};
}
})();
When function foo is fired I want to generate properties in $scope with names listed in the data array.
For example:
In function foo I want to create properties with names according to the strings in the data array:
$scope.bla1
$scope.bla2
$scope.bla3
How can I implement this?
Yes, in your 'foo' function:
for(var i = 0; i < data.length; i++) {
$scope[data[i]];
}
Did you try like this -
(function () {
"use strict";
angular.module("workPlan").controller("genericFilterDataController", ["$scope", genericFilterDataController]);
function genericFilterDataController($scope) {
$scope.data = ['bla1', 'bla2', 'bla3'];
$scope.foo = function ()
{
for(var i = 0; i < $scope.data.length; i++)
{
$scope[$scope.data[i]] = $scope.data[i];// or your data point here
}
};
}
})();
I declare $scope.something in my controller like
app.controller('MainControl', function($scope){
$scope.something = 1;
});
then how can I access it in my filter scope? like
app.filter("myCustomFilter", function () {
// here
});
obviously it doesn't work if I just $scope.something there.
After a chat here is the working solution http://jsbin.com/juxebewu/4/edit
<div ng-controller="sCtr">
<ul>
<li>{{aa | friends:this}}</li></ul>{{showItem}}
<p ng-show="showItem">click</p>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
var app = angular.module('App', []);
var targetOfFriendTasks = 1;
var user = [];
user[0]= {uId: 1};
app.filter("friends", function () {
return function (input, s) {
var output = [];
for (var i in input) {
if (input[i].name.length >= 1 && input[i].uId == targetOfFriendTasks) {
output.push(input[i]);
}
}
if (targetOfFriendTasks != user[0].uId) {
return output;
} else {
s.showItem = true;
}
};
});
app.controller('sCtr', function ($scope) {
$scope.aa = [{name:"lorem", uId:1}, {name:"ipsum", uId:2}];
$scope.showItem = false;
});