AngularJS share function/common code in a controller - javascript

I have a subroutine I want to use in my controller. In the case or working with data, a new record blanks fields, as would a screen clear, and after some other processes, I would like to clear the editable fields on the view.
Controller:
angular.module('MyApp').controller('Ctrl', ["$scope", "ServiceData",
function ($scope, ServiceData) {
function ClearMemberStruture()
{
$scope.member.Key = "";
$scope.member.Name = "";
$scope.member.Points = 0;
$scope.EditMode = false;
}
$scope.Members = ServiceData.GetAllMembers();
$scope.member = {};
ClearMemberStruture();
$scope.DeleteMember = function(Member) {
ServiceData.DeleteMember(Member.Key);
$scopeEditMode = false;
};
$scope.EditMember = function(Member) {
var EditMember = ServiceData.GetOneMember(Member.Key);
EditMember.$bindTo($scope, "member").then(
function(unbind) {
$scope.MemberUnbind = unbind;
});
$scopeEditMode = true;
};
$scope.SaveMember = function(Member) {
if( ! $scopeEditMode )
{
$scope.member = ServiceData.AddMember(Member);
ClearMemberStructure();
}
};
$scope.ClearMember = function() {
$scope.member.unbind;
ClearMemberStructure();
$scope.MemberUnbind();
};
}
]);
ClearMemberStructure() is used to reset the common structure fields and the Edit flag which controls showing information on the screen. When I run this code, I always get a
ReferenceError: ClearMemberStructure is not defined
How can I share this common function in my controller in AngularJS?
If I add a Factory, I can achieve this using calls to the factory:
angular.module('MyApp').factory("MemberRecord", function() {
var Member = {
Key: "",
Name: "",
Points: ""
};
return {
Clear: function() {
Member.Key = "";
Member.Name = "";
Member.Points = "";
return Member;
}
};
}
);
And then in the controller:
$scope.member = MemberRecord.Clear();
Is there a way to do the simply function style code sharing, as I do want this to be handled as a private function, but cannot get it to recognize the function in the controller.

var ClearMemberStruture = function()
{
$scope.member.Key = "";
$scope.member.Name = "";
$scope.member.Points = 0;
$scope.EditMode = false;
}
is your solution to declare ClearMemberStruture without breaking your whole code.

I use a separate file with factories to share code between controllers.
App.factory('CommonServices', function ($http) {
return {
createComment: function($api_key, $post_id, $comment) {
var comment_data = {
content: $comment
};
return $http({
url: '/api/v1/posts/' + $post_id + '/comments',
method: "POST",
headers: { 'X-API-TOKEN': $api_key },
params: comment_data,
data: ''
})
}
});
Then in a controller you can access the common functions like:
$scope.saveComment = function($post_id) {
CommonServices.createComment($scope.api_key, $post_id, $scope.comment.text)
.then(function(_data) {
var index = $scope.feed_items.filter(function (post) { return post.id == $post_id });
index[0].comments.unshift(_data.data);
$scope.showComment = false;
});
}

I prefer to use factory for Member and encapsulate method there. But you can try the easier way:
angular.module('MyApp').controller('Ctrl', ["$scope", "ServiceData",
function ($scope, ServiceData) {
var that = this;
that.ClearMemberStruture = function()
{
$scope.member.Key = "";
$scope.member.Name = "";
$scope.member.Points = 0;
$scope.EditMode = false;
}
$scope.Members = ServiceData.GetAllMembers();
$scope.member = {};
that.ClearMemberStruture();
$scope.DeleteMember = function(Member) {
ServiceData.DeleteMember(Member.Key);
$scopeEditMode = false;
};
$scope.EditMember = function(Member) {
var EditMember = ServiceData.GetOneMember(Member.Key);
EditMember.$bindTo($scope, "member").then(
function(unbind) {
$scope.MemberUnbind = unbind;
});
$scopeEditMode = true;
};
$scope.SaveMember = function(Member) {
if( ! $scopeEditMode )
{
$scope.member = ServiceData.AddMember(Member);
ClearMemberStructure();
}
};
$scope.ClearMember = function() {
$scope.member.unbind;
ClearMemberStructure();
$scope.MemberUnbind();
};
}
]);

Related

share objects between controllers using services [duplicate]

This question already has answers here:
Share data between AngularJS controllers
(11 answers)
Closed 5 years ago.
I have to controllers the first controller is "cockpitController"and the other one "idCardSupplierWarnController" .In the first controller i set my objects and i checked if the set work and it work i can see all my objects but when i want to get my objects in the other controller then all my objects are null .
PS: I checked this solution it's working for the case that the controller is in the same Window of the navigator but in my case it's in new window using $window.open(url).
Le service idCardSupplierWarnService :
var app = angular.module('idCardSupplierWarn');
app.service('idCardSupplierWarnService', function () {
this.idRefNum = "";
this.idSupNum = "";
this.codeSuppNum = "";
this.setParam = function (paramSet) {
console.log(paramSet);
this.idRefNum = paramSet.designRefPart;
this.idSupNum = paramSet.idSuppNumber;
this.codeSuppNum = paramSet.codeSupp;
};
this.getParamSupNum = function () {
return this.idSupNum;
};
this.getParamCodeSupNum = function () {
return this.codeSuppNum;
};
this.getParamIdRefNum = function () {
return this.idRefNum;
};
});
Le controller cockpitController :
(function () {
angular
.module("cockpit", ['mm.foundation', 'security', 'message', "isteven-multi-select"])
.controller('cockpitController', ['$scope', '$translate', 'serviceCockpit','idCardSupplierWarnService', '$window', function ($scope, $translate, serviceCockpit,idCardSupplierWarnService,$window) {
var urlSuppliersWarning = 'rest/suppliers/warnings';
var urlSuppliersWarningByRefForDetails = 'rest/suppliers/warnings/supplier/ref/search';
var self = this;
serviceCockpit.loadData([urlSuppliersWarning]).then(function (results) {
self.suppliersWarning = results[0].data;
});
this.change = function () {
if (this.openWindow) {
this.openWindow = false;
}
else {
this.openWindow = true;
}
};
$scope.openNewWindowRef = function (url, params) {
console.log(params);
idCardSupplierWarnService.setParam(params);
console.log(idCardSupplierWarnService.getParams());
$window.open(url, '_blank', 'left=0, top=0, width=1100,height=600,scrollbars=yes, resizable=1');
};
$scope.openNewWindowSupp = function (url, params) {
idCardSupplierWarnService.setParam(params);
console.log(idCardSupplierWarnService);
$window.open(url, '_blank', 'left=0, top=0, width=1100,height=600,scrollbars=yes, resizable=1');
};
this.process = function (items) {
if (items.origin == 'reference' || items.origin == 'suppliers' || items.origin == 'supplierAccounts' || items.origin == 'supplierAddressCodes' || items.origin == 'reset') {
serviceCockpit.loadData([urlSuppliersWarningByRefForDetails], items).then(function (results) {
self.suppliersWarningDetails = results[0].data;
});
}
serviceCockpit.loadData([urlSuppliersWarning], items).then(function (results) {
self.suppliersWarning = results[0].data;
});
}
}]);
})();
Le controller **idCardSupplierWarnController :**
(function () {
angular
.module("idCardSupplierWarn", ['mm.foundation', 'security', 'message', "isteven-multi-select"])
.controller('idCardSupplierWarnController', ['$translate', '$scope', 'serviceCockpit','idCardSupplierWarnService', function ($translate, $scope, serviceCockpit,idCardSupplierWarnService) {
var urlSupplierWarningByRefDetail = 'rest/suppliers/warnings/supplier/details';
var self = this;
var params = {} ;
params.idRefNum = idCardSupplierWarnService.getParamIdRefNum();
params.idSupNum = idCardSupplierWarnService.getParamSupNum();
params.codeSuppNum = idCardSupplierWarnService.getParamCodeSupNum();
console.log(params.codeSuppNum);
serviceCockpit.loadData([urlSupplierWarningByRefDetail], params).then(function (results) {
self.suppliersWarningsList = results[0].data;
});
}]);
})();
"This" in the functions of your service refers to the individual functions in your service, not the service itself.
Modify your service to look like this:
app.service('idCardSupplierWarnService', function () {
var service = this
service.idRefNum = "";
service.idSupNum = "";
service.codeSuppNum = "";
service.setParam = function (paramSet) {
console.log(paramSet);
service.idRefNum = paramSet.designRefPart;
service.idSupNum = paramSet.idSuppNumber;
service.codeSuppNum = paramSet.codeSupp;
};
service.getParamSupNum = function () {
return service.idSupNum;
};
service.getParamCodeSupNum = function () {
return service.codeSuppNum;
};
service.getParamIdRefNum = function () {
service this.idRefNum;
};
return service
});
You need to inject idCardSupplierWarn module into cockpit module, to access the service.
angular.module("cockpit", ['mm.foundation', 'security', 'message', `isteven-multi-select`, `idCardSupplierWarn`])

Controller isn't counted as a function

I have many different controllers throughout this project and all of them are declared the same way. This one now isn't getting called/giving an error and I have no clue why. I've looked through it and it all looks right to me.
I think it's probably some syntax error I'm not seeing. If its something else please tell me. I'm trying to learn angular and everything helps. Also if you need anything else just tell me.
I've made sure its not that the app.js name got changed and been looking for missing syntax but can't find anything.
https://docs.angularjs.org/error/ng/areq?p0=companyDepartmentController&p1=not%20a%20function,%20got%20undefined
company-department-controller.js
app.controller('companyDepartmentController', ['$scope', '$timeout', 'companyService', function ($scope, $timeout, companyService) {
/**
* Create/Manage Company Departments & Shifts
*
*/
// INITIALIZE VARIABLES *********************************************************************************
var vm = this;
vm.Departments = [];
vm.activeDepartment = {}
vm.departmentBeforeEdit = {};
vm.activeShift = {};
vm.OffsetString = "";
vm.SaveDepartmentSuccessMessage = null;
vm.SaveDepartmentErrorMessage = null;
// STARTUP **********************************************************************************************
(vm.GetDepartments = function () {
companyService.GetDepartmentsWithShiftInformation().success(function (data) {
console.log('hi');
for (i = 0; i < data.length; i++) {
console.log(data[i])
}
vm.Departments = data;
// for now we are limiting this to 1
vm.activeDepartment = vm.Departments[0];
vm.setTimeZoneOffsets(vm.activeDepartment);
});
})();
// move to global location? handle this better?
(vm.findLocalOffsetString = function () {
console.log('hi1');
vm.OffsetString = moment(new Date()).format('ZZ');
})();
// $BROADCAST/$ON EVENTS ********************************************************************************
// EVENTS ***********************************************************************************************
vm.saveDepartment = function (department) {
// new
if (department.DepartmentID === 0 || typeof department.DepartmentID === 'undefined') {
}
// update
else {
companyService.UpdateDepartmentHeader(department).success(function (data) {
vm.SaveDepartmentSuccessMessage = "Saved!";
resetDepartmentMessage();
department.InEdit = false
});
}
};
vm.editDepartment = function (department) {
vm.activeDepartment = department;
vm.departmentBeforeEdit = angular.copy(vm.activeDepartment);
vm.activeDepartment.InEdit = true;
};
vm.cancelDepartmentEdit = function (department) {
for (var i = 0; i < vm.Departments.length; i++) {
if (department.DepartmentID === vm.Departments[i].DepartmentID) {
vm.Departments[i] = vm.departmentBeforeEdit;
vm.departmentBeforeEdit = {};
vm.activeDepartment = vm.Departments[i];
break;
};
};
};
vm.addShift = function () {
if (!vm.activeDepartment) return;
vm.activeShift = {
DepartmentID: vm.activeDepartment.DepartmentID,
StartTime: new Date(),
LocalStartTime: new Date(new Date() + vm.OffsetString)
};
vm.activeShift.StartTime.setSeconds(0);
vm.activeShift.LocalStartTime.setSeconds(0);
};
vm.deleteShift = function (shift) {
if (!shift) return;
if (confirm("Are you sure you want to delete the shift: " + shift.Name + "?")) {
companyService.DeleteShift(shift).success(function () {
angular.forEach(vm.activeDepartment.Shifts, function (c, i) {
if (c.ShiftID === shift.ShiftID) {
vm.activeDepartment.Shifts.splice(i, 1);
};
});
});
};
};
vm.setTimeZoneOffsets = function (department) {
if (!department || !department.Shifts || department.Shifts.length === 0) return;
for (var i = 0; i < department.Shifts.length; i++) {
department.Shifts[i].LocalStartTime = new Date(department.Shifts[i].StartTime + vm.OffsetString);
department.Shifts[i].EndTime = moment(department.Shifts[i].StartTime).add(department.Shifts[i].Duration, 'hours').toDate()
};
};
var fixTimezoneOnSave = function (shift) {
shift.StartTime = new Date(shift.LocalStartTime).toLocaleString();
};
vm.setActiveShift = function (shift) {
if (!shift) return;
vm.activeShift = angular.copy(shift);
};
vm.saveShift = function (shift) {
fixTimezoneOnSave(shift);
// new shift
if (shift.ShiftID === 0 || typeof shift.ShiftID === 'undefined') {
companyService.AddShift(shift).success(function (data) {
shift.ShiftID = data;
vm.SaveDepartmentSuccessMessage = "Saved!";
resetDepartmentMessage();
getUpdatedShiftsAndInfo();
}).error(function (e) {
vm.SaveDepartmentErrorMessage = e.error;
resetDepartmentMessage();
});
}
// updating existing
else {
companyService.UpdateShift(shift).success(function (data) {
vm.SaveDepartmentSuccessMessage = "Saved!";
resetDepartmentMessage();
getUpdatedShiftsAndInfo();
}).error(function (e) {
vm.SaveDepartmentErrorMessage = e.error;
resetDepartmentMessage();
});
}
}
var getUpdatedShiftsAndInfo = function () {
companyService.DepartmentAndShiftInformation(vm.activeDepartment.DepartmentID).success(function (data) {
vm.activeDepartment.DepartmentShiftInformation = data.DepartmentShiftInformation;
vm.activeDepartment.Shifts = data.Shifts;
vm.setTimeZoneOffsets(vm.activeDepartment);
});
};
var resetDepartmentMessage = function () {
// clear error/success message if they have values still
if (vm.SaveDepartmentSuccessMessage != null) {
$timeout(function () { vm.SaveDepartmentSuccessMessage = null; }, 2000);
}
if (vm.SaveDepartmentErrorMessage != null) {
$timeout(function () { vm.SaveDepartmentErrorMessage = null; }, 2000);
}
};
// create controller object in console if we have logging turned on
if (spectrum.LoggingEnabled) {
spectrum.logController(vm);
};
}]);
_CompanyDepartment.cshtml
<div class="container-fluid" data-ng-controller="companyDepartmentController as cd">
</div>
#section scripts {
#Scripts.Render("~/bundles/companyDepartments")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/angularjs")
}
app.js
var app = angular.module('app', ['angularFileUpload', 'ngSanitize', 'ui.mask', 'ui.select', 'ui.bootstrap', 'ui.bootstrap.tpls', 'angular.filter', 'smart-table', 'colorpicker.module'])
.config(function ($httpProvider) {
//make delete type json to facilitate passing object
//to our generic method.
$httpProvider.defaults.headers["delete"] = {
'Content-Type': 'application/json;charset=utf-8'
};
});
Outside of a naming issue with the controller(which I can't see), I would imagine your issue dealing with the company-department-controller.js not being loaded.
In setting up your angular project, I would suggest that you follow this angular styleguide. It has been very helpful to me in creating a well structured project.

Use Javascript Object to Angular Service

I am trying to add functions to a JS Object which will be used as a singleton service.
angular
.module('app.steps')
.factory('createStepsService', createStepsService);
createStepsService.$inject = [];
/* #ngInject */
function createStepsService() {
var steps;
var service = {
newSteps: function (current_step, total_steps) {
if (!steps) {
return new Steps(current_step, total_steps);
}
}
};
return service;
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;
}
};
}
When I run this line from the controller, I am not able to access
addSteps / setLastStep methods.
vm.createStepsService = createStepsService.newSteps(1, 3);
Why I don't see these methods? Were they created?
Thanks.
Your steps.prototype code is never ran.
This is because it appears after the return.
Change the order of your code to this:
/* #ngInject */
function createStepsService() {
var steps;
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 = {
newSteps: function (current_step, total_steps) {
if (!steps) {
return new Steps(current_step, total_steps);
}
}
};
return service;
}
The reason that you can have a function declared before a return is because of JavaScript variable and function hoisting.
Your problem is that you are creating Steps.prototype after a return statement, so it will never be read.
In AngularJS, services are singletons objects that are instantiated only once per app.
And the factory() method is a quick way to create and configure a service.
It provides the function's return value i.e. Need to create an object, add properties to it, then it will return that same object.
For ex:
angular
.module('myApp',[])
.factory("createStepService", function(){
var stepServiceObj = {};
var c_step = 0;
var t_steps = 0;
var last_step = 0;
stepServiceObj.setCurrentStep = function(current_step){
c_step = current_step;
console.log('c_step1: ',c_step);
};
stepServiceObj.getCurrentStep = function(){
return c_step;
};
stepServiceObj.setTotalStep = function(total_steps){
t_steps = total_steps;
};
stepServiceObj.getTotalStep = function(){
return t_steps;
};
stepServiceObj.setLastStep = function(){
last_step = c_step = t_step;
};
stepServiceObj.getLastStep = function(){
return last_step;
};
stepServiceObj.addSteps = function(num){
return c_step += num;
};
return stepServiceObj;
});

Sharing object array between controllers while working with modal window in angularJS

I am trying to work with an object array which I am sharing among two controllers one of which is dealing with modal window.
Here is the js code.
angular.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache', 'ui.bootstrap'])
.service('Faq', function ($http) {
this.faqList = [];
this.faqList = $http.get('/Json/faq.json');
this.getFaqs = function ()
{
return this.faqList;
}
this.addfaq = function (obj) {
this.faqList.push(obj);
};
})
.controller('AppCtrl', function ($scope,$modal,Faq) {
$scope.faqData = [];
Faq.getFaqs().then(function (msg) {
$scope.faqData = msg.data;
});
}
$scope.show = function () {
$modal.open({
templateUrl: "faqAddUpdate.html",
controller: "faqctrl"
});
};
})
.controller('faqctrl', function ($scope, $modalInstance, Faq) {
$scope.question = '';
$scope.id = '';
$scope.answer = '';
$scope.editFaq = function (id) {
$scope.divFaq = true;
$scope.faqs = [];
Faq.getData().then(function (msg) {
$scope.faqs = msg.data;
var l = $scope.faqs.length;
for (var i = 0; i < l; i++) {
if ($scope.faqs[i].id == id) {
$scope.question = $scope.faqs[i].question;
$scope.id = $scope.faqs[i].id;
$scope.answer = $scope.faqs[i].answer;
}
}
});
};
$scope.AddUpdateFAQ = function () {
var faq = {
id: $scope.id,
question: $scope.question,
answer: $scope.answer
};
Faq.addfaq(faq);
console.log(faq);
$modalInstance.close();
};
$scope.Cancel = function () {
$modalInstance.dismiss();
};
});
but when I am submitting the data through the modal it says this.faqList.push is not a function.
It is because your faqList variable is not an array.
You overide the first definition:
this.faqList = [];
With this:
this.faqList = $http.get('/Json/faq.json');
But $http.get returns a promise (see doc), not an array.
You should do something like this:
this.faqList = [];
$http.get('/Json/faq.json').then(function(result) {
// process your results here
this.faqList = result.data;
});
Not tried, but this is within the function scope, so create a _this var first might help:
this.faqList = [];
this.faqList = $http.get('/Json/faq.json');
var _this = this;
this.getFaqs = function ()
{
return _this.faqList;
}
this.addfaq = function (obj) {
_this.faqList.push(obj);
};

issue: dual selectlist moving all items

below code is about dual selectlist. as shown in below image.
Its working as desire. Only problem is, if I click on last subject from Right hand side list box (select Subject list), it is moving all subject to left list box. Technically it should only move the clicked (selected) one subject.
Any suggestion to resolve this?
Code is as following
(function () {
'use strict';
angular
.module("eSchoolSystem")
.directive('multiSelect',['$compile', '$log', multiSelect])
function multiSelect($compile, $log) {
return {
restrict: 'E',
scope: {
name: '#',
selectedModel: '=',
availableModel: '='
},
/*template: '<select id="{{name}}-available" multiple ng-model="availableModel" ng-click="toSelected()" ng-options="a as a.subjectShortName for a in Model.available"></select>\n\n\
<select id="{{name}}-selected" ng-click="toAvailable()" multiple ng-model="selectedModel" ng-options="s as s.subjectShortName for s in Model.selected"></select>',
*/
templateUrl:'app/class/html/dualMultiSelect.html',
compile: function() {
return {
pre: function($scope, $elem, $attr) {
var RefreshSelect = function(original, toFilter) {
var filtered = [];
angular.forEach(original, function(entity) {
var match = false;
for (var i = 0; i < toFilter.length; i++) {
if (toFilter[i]["subjectId"] === entity["subjectId"]) {
match = true;
break;
}
}
if (!match) {
filtered.push(entity);
}
});
return filtered;
};
var RefreshModel = function() {
/*$scope.selectedModel = $scope.Model.selected;*/
$scope.selectedModel = angular.copy($scope.Model.selected);
/*$scope.availableModel = $scope.Model.available;*/
$scope.availableModel = angular.copy($scope.Model.available);
};
var Init = function() {
$scope.Model = {
available: $scope.availableModel,
selected: $scope.selectedModel
};
$scope.selectedModel = [];
$scope.availableModel = [];
$scope.toSelected = function() {
$scope.Model.selected = $scope.Model.selected.concat($scope.availableModel);
$scope.Model.available = RefreshSelect($scope.Model.available, $scope.availableModel);
RefreshModel();
};
$scope.toAvailable = function() {
console.log("in here -x1")
console.log("x3-> " + JSON.stringify($scope.selectedModel))
$scope.Model.available = $scope.Model.available.concat($scope.selectedModel);
$scope.Model.selected = RefreshSelect($scope.Model.selected, $scope.selectedModel);
RefreshModel();
};
};
Init();
}
};
}
};
}
}());
Try to remove RefreshModel function and updating selected values in toSelected and toAvailable:
$scope.toSelected = function() {
$scope.Model.selected = $scope.Model.selected.concat($scope.availableModel);
$scope.Model.available = RefreshSelect($scope.Model.available, $scope.availableModel);
$scope.selectedModel = $scope.availableModel;
$scope.availableModel = [];
};
$scope.toAvailable = function() {
$scope.Model.available = $scope.Model.available.concat($scope.selectedModel);
$scope.Model.selected = RefreshSelect($scope.Model.selected, $scope.selectedModel);
$scope.selectedModel = [];
$scope.availableModel = $scope.selectedModel;
};

Categories

Resources