Unit test case in AngularJS - angularjs

I am new to AngularJS. I have learned some basic of it. Now, I need to work on a AngularJS project at my work. I needed to create a function which I have successfully created. Below is my method.
vm.selectAll = function () {
var items = this.data;
for (var i = 0; i < items.length; i++) {
if ((vm.chkAll)) {
if (!items[i].AssignedToZone) {
if (!svcPermission.ensurePermission('AddPermission')) return;
svcZones.addPlace(Id, items[i].Id).then(refresh);
}
}
else {
if (!svcPermission.ensurePermission('DeletePermission')) return;
svcZones.removePlace(vm.selectedZone.Id, items[i].Id).then(refresh);
}
}
angular.forEach(items, function (item) {
item.AssignedToZone = vm.chkAll;
});
But , now my manager asked me to write unit test case for this method. I have googled it but I did not understand that from here I can start. I need to use Jasmine and mocha as these are already used it in current project.

Related

AngularJS - Delete check box is not working correctly and only deleting one at a time

I've written out a block of code that allows the user to check or uncheck entities that will be added or removed via web services. My add function seems to be working correctly and provides the ability to add multiple entities. However, my delete function isn't working the same. It doesn't delete each time, and can only delete one at a time. I'm struggling since the code is effectively the same as the add, so I don't know if the issue is AngularJS related or perhaps my web service isn't working correctly.
Edit: I've actually noticed that the for loop goes through it all but doesn't select the correct id, it always starts from the first one.
var toDeleteService = [];
for (var i = 0; i < $scope.siteServices.length; i++) {
if ($scope.siteServices[i].chosen != $scope.siteServices[i].origChosen) {
if ($scope.siteServices[i].chosen == true) {
toAddService.push(i);
}
else {
toDeleteService.push(i);
}
}
}
if (toDeleteService.length > 0) {
var deleteRequest = {};
deleteRequest.services = [];
for (var i = 0; i < toDeleteService.length; i++) {
var parentServiceName = $scope.siteServices[i].parentServiceName;
var j = 0;
for (; j < deleteRequest.services.length; j++) {
if (deleteRequest.services[j].parentServiceName == parentServiceName) {
break;
}
}
if (j == deleteRequest.services.length) {
deleteRequest.services[j] = {};
deleteRequest.services[j].parentServiceName = parentServiceName;
deleteRequest.services[j].subservices = [];
}
var service = {};
service.serviceId = $scope.siteServices[i].serviceId;
deleteRequest.services[j].subservices.push(service);
}
var deleteUrl = "api/sites/" + $scope.targetEntity.siteId + "/services/" + service.serviceId;
$http.delete(deleteUrl)
.then(function (response) {
});
}
As I understood it you are trying to remove siteServices based by numbers stored in var toDeleteServices = [] so you need to access those numbers by its index. but in service.serviceId = $scope.siteServices[i].serviceId; you are using i instead.
service.serviceId = $scope.siteServices[toDeleteServices[i]].serviceId; as you need actual number of the service to delete.
If I understood your code correctly.

Code works in Plunkr but not when outputting from my editor

I have made a custom filter to filter a list with multiple criteria on one column.
I have made this plunk
var app = angular.module('main', ['angular.filter'])
.filter('filterIns', function() {
var obj = {};
return function(list, ins) {
var out = [];
for (var i = 0; i < list.length; i++) {
if (ins.indexOf(list[i].instrument) > -1) {
obj = list[i];
out.push(obj);
}
}
if (ins.length === 0) {
out = list;
}
return out;
};
})
[...]
Everything is working as expected. However when I copy this code to my localhost environment I get this nasty, (general?) error: 'undefined is not an object (evaluating 'list.length')' referring to line 11.
Why is it working perfectly in Plunkr but not on localhost?
Can anybody tell me?
Is your list loaded async or something? Clearly it is undefined when the filter runs for the first time. So just place a condition before line 11, like:
if (!list) { return []; }
// or
if (!list) { return undefined; }
// or even better
if (!list) { return list; } // this keeps things like 0, undefined or null intact
and you should be safe.

Singleton JS Object in Angular Service

I am trying to add methods to an Object's protoype, which will be used in a singleton service and will be initiated only once when the service is created.
angular
.module('app.steps')
.factory('stepsService', stepsService);
stepsService.$inject = [];
/* #ngInject */
function stepsService() {
var steps = new Steps(1,3);
function Steps(current_step, total_steps) {
this.c_step = current_step;
this.t_step = total_steps;
}
Steps.prototype = {
addSteps: function (num) {
this.c_step += num;
},
setLastStep: function () {
this.lastStep = this.c_step = this.t_step;
}
};
var service = {
steps: steps
};
return service;
}
My problem is that although the object is created and initiated successfully, the methods are not there.
What is missing?
As mentioned in the comments, var steps = new Steps(1,3); should be after Steps.prototype = {....}

Elasticsearch: AngularJS & Aggregations

I am using elasticsearch (version 2.2.0) and discovered that angular.js can be used to create front end UI. (I am a complete newbie to angular.js, and overall programing itself).
I am following an online tutorial and cant seem to get the aggregations passed from elasticsearch to the angular object, though I can view the aggregation in curl command on terminal. Is there something wrong, that I can fix. I want to be able to see the aggregations passed to the object, so that I can use it to create a front end UI based filter list.
searchApp.service('filterService', [function(){
this.filters ={
availableFilters:{},
selectedFilters: []
};
this.findSelectedFilter= function(field,value) {
var selectedFilters = this.filters.selectedFilters;
for (var i=0; i<selectedFilters.length; i++) {
var obj = selectedFilters[i];
if (obj.field == field && obj.value == value) {
return i;
}
}
return -1;
};
this.formatFilters = function(aggregations) {
var self=this;
var formattedFilters = {};
for (var aggregation in aggregations) {
if(aggregations.hasOwnProperty(aggregation)) {
var filters = aggregations[aggregation].buckets.map(function(obj){
var isSelected = function() {
return self.findSelectedFilter(aggregation, obj.key) == -1 ? false:true;
};
return {
value: obj.key,
count: obj.doc_count,
isSelected: isSelected()
}
});
formattedFilters[aggregations] = filters;
}
}
}
}]);
(PS: I have seen elastic-UI, which works , but want to try this method).
Thanks a lot!!

Angular - Organise controller, factory and "class"

I would like to understand how to have a nice organisation in my angular project.
[see code below]
Does it makes sense to have the getFireList function into the Factory ? Or should i put it into the controller ?
Does the "class" Fire makes sense ? Should i remove it ? Should i move it to the controller ? Should i move it the the factory ?
If you see anything wrong in this code i'm really interested to learn more.
For now, i've got this :
A class "Fire" to create new object of type Fire.
function Fire (p_power) {
// ATTRIBUTES
this.id = null;
this.power = p_power;
this.position = {
x: null,
y: null
}
// GETTERS/SETTERS
// id
this.getId = function() {
return this.id;
}
this.setId = function(p_id) {
this.id = p_id;
}
// power
this.getPower = function() {
return this.power;
}
this.setPower = function(p_power) {
this.power = p_power;
}
// position
this.getPosition = function() {
return this.position;
}
this.setPosition = function(p_position) {
this.position = p_position;
}
// METHODS
this.increasePower = function(p_plus) {
this.power += p_plus;
}
this.decreasePower = function(p_minus) {
this.power -= p_minus;
}
}
A controller
simuApp.controller('FireController', function($scope, FireFactory) {
// ...
});
And a factory
simuApp.factory('FireFactory', function() {
return {
fire_list: [],
getFireList : function() {
return $http.get(site_url+'fire/fireList').
then(
function(success) {
var data = success.data;
var fires = [];
var fire_tmp;
for (i=0 ; i<data.length ; i++) {
fire_tmp = new Fire( data[i].power );
fire_tmp.setId( data[i].idFire );
fires.push( fire_tmp );
}
fire_list = fires;
return fire_list;
}, function(err) {
// ...
}
);
}
}
});
Thanks for your help.
First, let's get the terminology right. .factory is a method to register a function that generates an instance of the service - hence "factory". What it generates, though, is a singleton service instance.
So, the service you create would be more properly named as FireSvc (as opposed to FireFactory), whereas the function that creates it could have the word "factory" in it (although, in the case below, that function name is not really needed - it could just be an anonymous function):
.factory("FireSvc", function FireSvcFactory(){
});
It is a good practice to use a Service to abstract away any domain/business logic from the controller. Keep the controller thin, responsible only to define the ViewModel, and react to events by changing the ViewModel or invoking functions on the Model.
So, having FireSvc.getFireList() makes sense.
Now, whether the list is a collection of plain objects, or instances of Fire is completely independent of Angular and is entirely up to you. In any case, it is too broad of a topic to discuss in a SO answer.

Resources