I have two angularjs function in my dataContext object that receive data from an webapi as you can see below
(function () {
'use strict';
var serviceId = 'datacontext';
angular.module('app').factory(serviceId,
['common', datacontext]);
function datacontext(common) {
var service = {
getAllTagsByHttp: getAllTagsByHttp,
getBlogPostsByHttp: getBlogPostsByHttp,
getAllUserPicByHttp: getAllUserPicByHttp
};
return service;
function getAllTagsByHttp() {
return common.$http.get('/api/TagApi/alltags');
}
function getBlogPostsByHttp() {
return common.$http.get('/api/BlogPostApi/AllBlogPosts');
}
function getAllUserPicByHttp() {
return common.$http.get('/api/BlogPostApi/AllUserPic');
}
}})();
I have an angularjs controller that call these api functions from the datacontext to receive information to display back to the user. The getblogPost function is called first because the next function need's the data from this to operate on.the second function does a comparison on the first function's data to display back the img source to the user. The problem i am having is that it takes quite a few seconds for the second function to receive the data and an complete its operation. The amount of data being send back is a few records.Is there any improvements that can be made to controller or data Context object to reduce the time or improve the code?
(function () {
'use strict';
var controllerId = 'search';
angular
.module('app')
.controller(controllerId, ['common','datacontext', search]);
function search(common, datacontext) {
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
var vm = this;
vm.title = 'search';
vm.picData = [];
activate();
function activate() {
var promises = [getBlogPosts(), getUserPicData(), getUserPicUrl()];
common.activateController(promises, controllerId)
.then(function () { log('Search View'); });
}
function getBlogPosts() {
datacontext.getBlogPostsByHttp().then(function (response) {
vm.data = response.data;
});
}
function getUserPicData() {
datacontext.getAllUserPicByHttp().then(function (response) {
vm.picData = response.data;
for (var i = 0; vm.data.length > i; i++) {
for (var x = 0; vm.picData.length > x; x++) {
if (vm.data[i].UserName == vm.picData[x].UserName) {
vm.data[i].PictureUrl = vm.picData[x].PictureUrl;
// console.log(vm.data[i].PictureUrl);
break;
}
}
}
});
}
function getUserPicUrl(username) {
getUserPicData();
for (var i = 0; vm.picData.length < i; i++) {
if (vm.picData[i].UserName === username) {
return vm.picData[i].PictureUrl;
}
}
return "not found";
}
}})();
Related
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`])
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.
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;
});
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);
};
I am trying to make an angular service that returns a new object.
That's fine and good and works. new MakeRoll() creates an instance. But self.add, near the end also calls new MakeRoll() and that doesn't create an instance when I call add like I think it should.
I'm probably doing this all wrong but I haven't been able to figure it out.
var services = angular.module('services', []);
services.factory('Roll', [function() {
var MakeRoll = function () {
var self = {};
self.rolls = [];
self.add = function(number, sizeOfDice, add) {
var newRoll = {};
newRoll.number = number || 1;
newRoll.sizeOfDice = sizeOfDice || 6;
newRoll.add = add || 0;
newRoll.rollDice = function() {
var result = 0;
var results=[];
for (var i = 0; i < newRoll.number; i++) {
var roll = Math.floor(Math.random() * newRoll.sizeOfDice) + 1;
result += roll;
results.push(roll);
}
newRoll.results = results;
newRoll.result = result;
newRoll.Roll = new MakeRoll();
};
self.rolls.push(newRoll);
return self;
};
self.remove = function(index) {
self.rolls.splice(index, 1);
};
self.get = function(index) {
return self.rolls[index];
};
return self;
};
return new MakeRoll();
}
]);
angular service is designed to be singleton to accomplish some business logic, so don't mix up plain model with angular service. if you want to have more objects, just create a constructor and link it in service to be operated on.
function MakeRoll() {
...
}
angular.module('service', []).factory('Roll', function () {
var rolls = [];
return {
add: add,
remove: remove,
get: get
}
function add() {
// var o = new MakrRoll();
// rolls.push(o);
}
function remove(o) {
// remove o from rolls
}
function get(o) {
// get o from rolls
}
});