I have a factory called search
.
I have many controllers called SearchCampaignController
, SearchQuotaController
and so on.
The factory search
is a singleton object to which these controllers add function implementations to.
The problem is, a parent controller called SearchController
must call a function inside the factory search
which is not yet implemented because the child controllers execute after the parent controller executes.
It seems like I'm doing something wrong.
angular
.module('app.search')
.factory('search', search);
search.$inject = ['$http', '$window', '$state', 'CONF', '$mdToast', 'USER_ROLES', 'USER_MODULES'];
function search($http, $window, $state, CONF, $mdToast, USER_ROLES, USER_MODULES) {
var searchInfo;
function updateQueryString(params) {
$state.go(
'search',
{
searchType: params.searchType,
quotaId: params.quotaId,
campaignName: params.campaignName,
templateName: params.templateName,
passId: params.passId,
certId: params.certId
},
{notify: false}
)
}
function getQuotaById(params) {
var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId;
return $http.get(reqPath);
}
function getCampaignById(params) {
var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId + '/campaigns/' + params.campaignName;
return $http.get(reqPath);
}
function queryCampaigns(params) {
var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId + '/campaigns';
return $http.get(reqPath);
}
function getTemplateById(params) {
var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId + '/campaigns/' + params.templateName;
return $http.get(reqPath);
}
function queryTemplates(params) {
var reqPath = CONF.apiPath + 'core/campaigns/' + params.campaignName + '/templates';
return $http.get(reqPath);
}
function getPassById(params) {
var reqPath = CONF.apiPath + 'core/passes/' + params.passId;
return $http.get(reqPath);
}
function getPassbookById(params) {
var reqPath = CONF.apiPath + 'core/passbookCert/' + params.certId;
return $http.get(reqPath);
}
function queryPassbookCerts(params) {
var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId + '/passbookCerts';
return $http.get(reqPath);
}
//Global search logic
//NEED TO RE-FACTOR
function searchMasterFunction(params, obj) {
if(params.searchType){
search.changeSearchType(params.searchType);
}
updateQueryString(params);
if(params.quotaId){
search.getQuotaAndDisplayResult(params);
// search.getPassbookCertsAndDisplayResult(params);
search.updateQuotaIdInTemplateTab(params); //special - needs re-visit
}
if(params.quotaId && !params.campaignName){
search.getCampaignsAndDisplayResult(params);
}
if(params.quotaId && params.campaignName && params.templateName){
search.getCampaignAndDisplayResult(params);
search.getTemplateAndDisplayResult(params);
}else if(params.quotaId && params.campaignName){
search.getCampaignAndDisplayResult(params);
search.getTemplatesAndDisplayResult(params);
}else if(params.quotaId && params.templateName){
search.getTemplateAndDisplayResult(params);
}
if(params.campaignName){
search.getTemplatesAndDisplayResult(params);
}
if(params.passId){
search.getPassAndDisplayResult(params);
}
//getPassbookById
}
var search = {
searchInfo: searchInfo,
searchMasterFunction: searchMasterFunction,
getQuotaById: getQuotaById,
getCampaignById: getCampaignById,
queryCampaigns: queryCampaigns,
getTemplateById: getTemplateById,
queryTemplates: queryTemplates,
getPassById: getPassById,
getPassbookById: getPassbookById,
queryPassbookCerts: queryPassbookCerts
};
return search;
}
And this is my parent controller which should call the searchMasterFunction inside the factory search
so that when there are values in the query string, it automatically populates any search results according to the logic inside the search
factory.
angular
.module('app.search')
.controller('SearchController', SearchController);
SearchController.$inject = ['$state', 'search', '$scope', '$log'];
function SearchController($state, search, $scope, $log){
$log.warn("Executing SearchController");
var vm = this;
vm.searchType = $state.params.searchType; //re-visit
vm.tabs = ['quota', 'campaign', 'template', 'pass', 'cert'];
vm.changeSearchTypeOnTabClick = changeSearchTypeOnTabClick;
search.changeSearchType = changeSearchType;
function changeSearchTypeOnTabClick(searchType) {
$state.go('search', {searchType: searchType}, {notify: false});
}
function changeSearchType(searchType) {
vm.searchType = searchType;
}
// this function call is what is causing the problem
// search.searchMasterFunction($state.params);
}
The following is one of my child controllers which implement functions such as search.getQuotaAndDisplayResult.
angular .module('app.search') .controller('SearchQuotaController', SearchQuotaController);
SearchQuotaController.$inject = ['search', '$scope', '$log'];
function SearchQuotaController(search, $scope, $log){
$log.info("Executing SearchQuotaController");
var vm = this;
vm.searchInfo;
vm.quota;
vm.searchBtnClick = searchBtnClick;
search.getQuotaAndDisplayResult = getQuotaAndDisplayResult; //THIS LINE IS WHAT NEEDS ATTENTION. I'm adding a function into the `search` factory.
function searchBtnClick(params){
search.searchMasterFunction(params);
};
function getQuotaAndDisplayResult(params) {
vm.searchInfo = params; //update fields in the Quota view
search.getQuotaById(params).then(function(quota){
vm.quota = quota.data; //update the quota object in the view
});
};
}
So the problem is that SearchQuotaController runs AFTER SearchController and therefore if I try to call search.searchMasterFunction in SearchController, it will not be able to execute properly since search.searchMasterFunction relies on the child controller to execute in order for the function implementation to be complete.
Any help would be greatly appreciated. I've already considered the $broadcast method but it seems like a hack and not a real solution.
PS. The reason why I'm adding functions from child controllers into the search
factory is because child controllers have access to their local $scope
.