I need to inject some piece of code into a function, to prevent DRY. Here is an example of my code.
angular.module('crypt', ['ui.chart'])
.controller('MainCtrl', ['$http', function($http) {
var self = this;
self.encrypt = function() {
$http.post('/encrypt',
{'crypt': {'text': self.plain, 'shift':self.rot}})
.then(function(response) {
self.encrypted = response.data.encrypted;
self.plain = '';
// reusable function goes here
// var frequencyArr = response.data.frequency;
// var frequencyArrLength = frequencyArr.length;
// if (frequencyArrLength) self.cryptChart = [frequencyArr];
});
};
self.decrypt = function() {
$http.post('/decrypt',
{'crypt': {'text': self.encrypted, 'shift':self.rot}})
.then(function(response) {
self.plain = response.data.plain;
self.encrypted = '';
// and here
// the stuff to become a function
var frequencyArr = response.data.frequency;
var frequencyArrLength = frequencyArr.length;
if (frequencyArrLength) self.cryptChart = [frequencyArr];
});
};
// ...
}])
So how do I pack that 3 lines and make a reusable function in Angular way?
Maybe like this:
angular.module('crypt', ['ui.chart'])
.controller('MainCtrl', ['$http', function($http) {
var self = this;
function cryption(decrypt, callBack) {
$http.post(
decrypt ? '/decrypt' : '/encrypt',
{crypt: {text: decrypt ? self.encrypted : self.plain, shift: self.rot }})
.then(callBack);
}
function cryptChart(response) {
var frequencyArr = response.data.frequency;
var frequencyArrLength = frequencyArr.length;
if (frequencyArrLength) // can be simplyfied to response.data.frequency.length
self.cryptChart = [frequencyArr];
}
self.encrypt = cryption(false, function(response) {
self.encrypted = response.data.encrypted;
self.plain = '';
cryptChart(response);
});
self.decrypt = cryption(true, function(response) {
self.plain = response.data.plain;
self.encrypted = '';
cryptChart(response);
});
// ...
}])
I went bit further and extracted the shared $http.post call into function as well.
Related
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!
erp.directive("auto1", [ '$http', function( $http) {
var mydata;
var x;
var y;
data = function(){
return $http.get("./php/fetchElement.php").then(function (response) {
mydata = this;
mydata = response.data.records;
});
};
function run(){
return data().then(function(response){
return mydata.map(function(ele){
return ele.Name;
});
});
}
x = run();
console.log(x);
return {
restrict: 'A',
link: function() {
$('#auto1').autocomplete({source:[x]})
}
};
}]);
Please help me! I cannot take the array "ele.Name" out of the function. When inside it is an expected array. But when assign to "x" it is a complicated object that I cannot access for desired value.
In the script below i try to access the data from the cartDataService, even though i manage to read this.test from the cartDataService, i get an empty value for the cart_id. I know it is due to the asynchronous characteristics of javascript
i am pretty sure that i try to access the cart_id from the service before it is assigned, how do i make sure that the cart_id from the service is assigned? thank you
var app = angular.module('myApp', [])
app.service('cartDataService', function () {
this.cart_id = ""
this.getcart_id = function(){ return this.cart_id};
this.setcart_id = function(id){
this.cart_id = id
}
this.test = "byebye"
})
app.controller('OrderDetailCtrl', ['$http', 'cartDataService', function ($http, cartDataService) {
var self = this
self.msg = 'Order Detail'
self.order_id = outer_id
self.orders = {
get: function () {
return $http.get('http://apimucommerce/api/order/' + self.order_id + '/')
.then(function (response) {
return response.data
})
}
}
self.orders.get().then(function (data) {
self.order = data
self.cart_id = self.order.cart_id
cartDataService.setcart_id(self.order.cart_id)
})
}])
app.controller('CartController', ['cartDataService', function (cartDataService) {
var self = this
self.cart_id = cartDataService.getcart_id()
alert(cartDataService.cart_id)
self.msg = cartDataService.test
}])
You can use this:
app.controller('CartController', ['$scope', 'cartDataService', function ($scope, cartDataService) {
var self = this
$scope.$watch(
function () watcher{
return cartDataService.getcart_id();
},
function () onCardIdChanged{
self.cart_id = cartDataService.getcart_id()
alert(self.cart_id);
}
);
}]);
Another way to solve your problem:
app.service('cartDataService', ['$q', function ($q) {
var deffered = $q.defer();
this.cart_id = "";
this.getcart_id = function(){
return deffered.promise;
};
this.setcart_id = function(id){
this.cart_id = id;
deffered.resolve(;
}
}]);
app.controller('CartController', ['$scope', 'cartDataService', function ($scope, cartDataService) {
var self = this;
cartDataService.getcart_id().then(function (cardId) {
self.cart_id = cartDataService.getcart_id()
alert(self.cart_id);
});
}]);
UPD:
app.service('cartDataService', ['$q', function ($q) {
var deffered = $q.defer();
this.cart_id = "";
this.getcart_id = function(){
return deffered.promise;
};
this.setcart_id = function(id){
this.cart_id = id;
deffered.resolve(id);
}
}]);
app.controller('CartController', ['$scope', 'cartDataService', function ($scope, cartDataService) {
var self = this;
cartDataService.getcart_id().then(function (cardId) {
self.cart_id = cardId;
alert(self.cart_id);
});
}]);
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;
});
Given the following code:
function Ctrl($scope, $http, $q) {
var search = function(name) {
if (name) {
$http.get('http://api.discogs.com/database/search?type=artist&q='+ name +'&page=1&per_page=5').
success(function(data3) {
$scope.clicked = false;
$scope.results = data3.results;
});
}
$scope.reset = function () {
$scope.sliding = false;
$scope.name = undefined;
};
};
$scope.$watch('name', search, true);
var done = $scope.getDetails = function (id) {
$scope.clicked = true;
$scope.sliding = true;
var api = 'http://api.discogs.com/artists/';
return $q.all([$http.get(api + id),
$http.get(api + id + '/releases?page=1&per_page=100')]);
};
done.then(function (){
$scope.releases = data2.releases;
$scope.artist = data;
return $http.get('http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=e8aefa857fc74255570c1ee62b01cdba&artist=' + name + '&album='+ title +'&format=json');
});
I'm getting the following console error:
TypeError: Object function (id) {
$scope.clicked = true;
$scope.sliding = true;
var api = 'http://api.discogs.com/artists/';
return $q.all([$http.get(api + id),
$http.get(api + id + '/releases?page=...<omitted>... } has no method 'then'
at new Ctrl (file:///C:/Users/Zuh/Desktop/AngularJS%20Discogs/js/services.js:27:9)
Can anybody point me to where might the error be? I'm defining the .then after getDetails is executed...
Here's a working Plunker.
Here is your updated plunkr http://plnkr.co/edit/lTdnkRB1WfHqPusaJmg2?p=preview
angular.module('myApp', ['ngResource']);
function Ctrl($scope, $http, $q) {
var search = function(name) {
if (name) {
$http.get('http://api.discogs.com/database/search?type=artist&q='+ name +'&page=1&per_page=5').
success(function(data3) {
console.log(arguments)
$scope.clicked = false;
$scope.results = data3.results;
});
}
$scope.reset = function () {
$scope.sliding = false;
$scope.name = undefined;
};
};
$scope.$watch('name', search, true);
var done = $scope.getDetails = function (id) {
$scope.clicked = true;
$scope.sliding = true;
var api = 'http://api.discogs.com/artists/';
var q = $q.all([$http.get(api + id),
$http.get(api + id + '/releases?page=1&per_page=100')])
.then(function (ret){
//console.log(arguments)
$scope.releases = ret[1].data.releases;
$scope.artist = ret[0];
return $http.get('http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=e8aefa857fc74255570c1ee62b01cdba&artist=' + name + '&album='+ title +'&format=json');
})
return q
};
}
To sum up fixes:
move $q.all().then() part into done method
pay more attention to what parameters handlers received in then part.