Automatically generating variables in AngularJS with specific names - javascript

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

Related

AngularJS 1.6.6 can't update the model value with $setViewValue

The Problem
Unable to update Model;
Using the set function I can change the ngModel value, and through the pipeline function $parsers, however the Del function uses splice to process the array, but it can not pass the pipeline function and realizes the update model value.
I tried to use $scope.$apply () to execute after ngModel.$setViewValue ($scope.images) and still can't be solved.
The version of the angular used is 1.6.6.
Online code, online code links, I hope you can help me to see where the problem is in the end.
View code
<div ng-controller="appController">
<div image-uploads ng-model="files"></div>
<p style="display: block; color: red">{{files}}</p>
</div>
Javascript code
var app = angular.module('app', []);
app.controller('appController', function ($scope) {
$scope.files = '1,2,3,4';
});
app.directive('imageUploads', function () {
return {
require: '?^ngModel',
restrict: 'EA',
template: '<div class="image-upload-box"><p class="image_upload" ng-repeat="image in images track by $index"><button ng-click="set()">setModel</button><button ng-click="del($index)">{{image}}</button></p></div>',
link: function ($scope, element, attrs, ngModel) {
ngModel.$formatters.push(function (modelValue) {
var images = new Array();
if (!ngModel.$isEmpty(modelValue)) {
var values = modelValue.split(",");
for (var j = 0; j < values.length; j++) {
images.push({
'id': values[j]
});
}
}
return images;
});
ngModel.$parsers.push(function (viewValue) {
var s = "";
for (var j = 0; j < viewValue.length; j++) {
if (viewValue[j].id != null) {
if (j > 0) {
s += ",";
}
s += viewValue[j].id;
}
}
return s;
});
ngModel.$render = function () {
$scope.images = ngModel.$viewValue;
};
$scope.del = function (i) {
$scope.images.splice(i, 1);
ngModel.$setViewValue($scope.images);
};
$scope.set = function () {
console.log('set');
$scope.images = [{id: 5}, {id: 6}, {id: 7}];
ngModel.$setViewValue($scope.images);
}
}
};
});

What is the best way to define a constant in an Angular controller?

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

ReferenceError $timeout is not defined angularjs

Here i add a delay in javascript forloop using $timeout. Unexpectedly i got an error saying
ReferenceError $timeout is not defined. i am new to angularjs please help me.
PLNKR
function CompLibrary() {
return {
init: init
}
function init(dependencies, controller) {
dependencies.push(controller);
angularApp.controller('MainCtrl', dependencies);
}
}
var compX = CompLibrary();
compX.init(deps, _controller);
function _controller() {
var ViewModel = this;
ViewModel.search = "Name";
ViewModel.quantity = 1;
for(var i = 0; i < 4; i++) {
(function(i){
$timeout(function() {
ViewModel.quantity++;
}, i * 2000);
})(i); // Pass in i here
}
}
You have to inject the $timeout into the controller function.
function _controller($timeout) { ... }
Please see updated Plunkr
var deps = [];
var angularApp = angular.module('plunker',[]);
function CompLibrary() {
return {
init: init
}
function init(dependencies, controller) {
dependencies.push('$timeout');
dependencies.push(controller);
angularApp.controller('MainCtrl', dependencies);
}
}
var compX = CompLibrary();
compX.init(deps, _controller);
function _controller($timeout) {
var ViewModel = this;
ViewModel.search = "Name";
ViewModel.quantity = 1;
for(var i = 0; i < 4; i++) {
(function(i){
$timeout(function() {
ViewModel.quantity++;
}, i * 2000);
})(i); // Pass in i here
}
}
By injecting $timeout in the controller function we can solve this problem.

How to remove and edit object from cookies in angularjs

I have a problem with remove and edit cookie object from $cookies in angularjs. I want to make a shop and I am adding products to $cookies global variable with putObject function (I didn't use put because I have more than one argument). I want to add function to remove and edit product from shop and remove and edit only one object from cookie. Please help me!
Here is a fragment of my code (I want to remove/edit object from 'products' cookie):
app.controller('Store', ['$scope', '$cookies', 'x2js', '$http',
function($scope, $cookies, x2js, $http){
this.products = $cookies.getObject('products');
if(!this.products) {
var self = this;
$http.get('assets/xml/products.xml').success(function(data) {
self.products = data.products.product;
for(var i = 0; i < self.products.length; i++) {
self.products[i].id = parseInt(self.products[i].id);
self.products[i].netto = self.products[i].netto + '.00';
self.products[i].tax = parseInt(self.products[i].tax);
self.products[i].brutto = parseFloat(self.products[i].brutto);
self.products[i].rating = parseInt(self.products[i].rating);
};
});
}
$scope.product = $cookies.getObject('product') || {};
$scope.$watch('product', function() {
$cookies.putObject('product', $scope.product);
}, true);
this.addProduct = function() {
if(this.countCategories() >= 2) {
if(this.validateForm()) {
var product = {
id: this.products.length + 1,
name: $scope.product.name,
code: $scope.product.code,
image: $scope.product.image,
netto: this.intToFloat($scope.product.netto, 2),
tax: $scope.product.tax,
brutto: this.calculatePriceBr(),
rating: parseInt(this.ratingChecked()),
category: this.categoryChecked(),
option: this.optionChecked(),
selected: $scope.product.selected
};
this.products.push(product);
$scope.product = {};
$cookies.putObject('products', this.products);
$('#product-add').modal('hide');
return true;
} else {
return;
}
} else {
return;
}
};
})();
Hope this is what you are looking for.
I've made a little test based on your code (simplified):
var app = angular.module('myApp', ['ngCookies']);
app.controller('Store', Store);
Store.$inject = ['$scope', '$cookies', '$http'];
function Store($scope, $cookies, $http) {
var vm = this;
vm.products = [];
vm.cart = [] ;
vm.inCookie =[];
$http.get('products.xml').success(function(data) {
vm.products = data;
for (var i = 0; i < vm.products.length; i++) {
vm.products[i].id = parseInt(vm.products[i].id);
vm.products[i].netto = vm.products[i].netto + '.00';
vm.products[i].tax = parseInt(vm.products[i].tax);
vm.products[i].brutto = parseFloat(vm.products[i].brutto);
vm.products[i].rating = parseInt(vm.products[i].rating);
};
});
this.addProduct = function(row) {
vm.cart.push(row);
$cookies.put('cart', JSON.stringify(vm.cart));
vm.inCookie = JSON.parse($cookies.get('cart'));
};
}
You can see here how to add and retrieve data from a cookie.
In this plunkr you can see it working.
https://plnkr.co/edit/ew1ePjzbMxjAqtgx8hzq?p=preview
Hope this helps.
Regards!

Moving code into a factory in an Angular app

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

Categories