angular.module('starter').controller('VariableSearchCtrl',
["$scope", "$state", "$rootScope", "$stateParams", "$timeout", "$filter", "qmService",
function($scope, $state, $rootScope, $stateParams, $timeout, $filter, qmService){
$scope.controller_name = "VariableSearchCtrl";
qmService.navBar.setFilterBarSearchIcon(false);
$scope.$on('$ionicView.beforeEnter', function(e){
qmLog.info($state.current.name + ' beforeEnter...');
qmService.navBar.showNavigationMenuIfHideUrlParamNotSet();
//qm.objectHelper.copyPropertiesFromOneObjectToAnother($stateParams, $scope.state, true);
$scope.state = JSON.parse(JSON.stringify($stateParams)); // Overwrites cached results. Necessary if in a different state
$scope.state.searching = true;
$scope.state.variableSearchResults = [];
if(!$scope.state.variableSearchParameters){$scope.state.variableSearchParameters = {};}
$scope.state.variableSearchParameters.searchPhrase = "";
if(!$scope.state.noVariablesFoundCard){
$scope.state.noVariablesFoundCard = {
show: false,
title: 'No Variables Found',
body: "You don't have any data, yet. Start tracking!"
};
}
if(!$scope.state.title){$scope.state.title = "Select Variable";}
if(!$scope.state.variableSearchPlaceholderText){$scope.state.variableSearchPlaceholderText = "Search for a variable here...";}
$scope.state.variableSearchParameters.variableCategoryName = getVariableCategoryName();
//$scope.showBarcodeScanner = $rootScope.platform.isMobile && (qm.arrayHelper.inArray($scope.state.variableSearchParameters.variableCategoryName, ['Anything', 'Foods', 'Treatments']));
if(getVariableCategoryName()){
$scope.state.variableSearchPlaceholderText = "Search for a " + getPluralVariableCategoryName().toLowerCase() + " here...";
$scope.state.title = "Select " + getPluralVariableCategoryName();
$scope.state.noVariablesFoundCard.title = 'No ' + getVariableCategoryName() + ' Found';
}
setHelpText();
});
$scope.$on('$ionicView.enter', function(e){
if (document.title !== $scope.state.title) {document.title = $scope.state.title;}
qmLog.info($state.current.name + ' enter...');
// We always need to repopulate in case variable was updated in local storage and the search view was cached
populateSearchResults();
setHelpText();
qmService.hideLoader();
var upcTest = false;
if(upcTest){
$scope.state.variableSearchParameters.barcode = $scope.state.variableSearchParameters.searchPhrase = "028400064057";
$scope.onVariableSearch(function(){
});
}
if(qm.urlHelper.getParam('upc')){
qmService.barcodeScanner.scanSuccessHandler({text: qm.urlHelper.getParam('upc')},
{}, function(variables){
console.log(variables)
}, function(error){
console.error(error);
})
}
});
$scope.$on('$ionicView.afterEnter', function(e){
$scope.helpCard = qmService.populateHelpCard($scope.helpCard, $stateParams)
});
function goToState(state, params){
params = JSON.parse(JSON.stringify(params));
params.measurement = null; // We send the measurement back after adding, so it might be stale
qmService.goToState(state, params);
}
function saveTagged(selected) {
if ($scope.state.userTagVariableObject.unitAbbreviatedName !== '/5') {
goToState(getNextState(), {
userTaggedVariableObject: selected,
fromState: $scope.state.fromState,
fromStateParams: {variableObject: $scope.state.userTagVariableObject},
userTagVariableObject: $scope.state.userTagVariableObject
});
} else {
qmService.showFullScreenLoader();
qmService.postUserTagDeferred({
userTagVariableId: $scope.state.userTagVariableObject.variableId,
userTaggedVariableId: selected.variableId,
conversionFactor: 1
}).then(function () {
qmService.hideLoader();
if ($scope.state.fromState) {
goToState($scope.state.fromState, {variableName: $scope.state.userTagVariableObject.name});
} else {
qmService.goToDefaultState();
}
});
}
}
function getNextState() {
var s = $state.current;
var next = s.params.nextState;
if(!next){
console.info("No next state!")
return null;
}
return next;
}
function saveTag(selected) {
if ($scope.state.userTaggedVariableObject.unitAbbreviatedName !== '/5') {
goToState(getNextState(), {
userTaggedVariableObject: $scope.state.userTaggedVariableObject,
fromState: $scope.state.fromState,
fromStateParams: {variableObject: $scope.state.userTaggedVariableObject},
userTagVariableObject: selected
});
} else {
qmService.showFullScreenLoader();
qmService.postUserTagDeferred({
userTagVariableId: selected.variableId,
userTaggedVariableId: $scope.state.userTaggedVariableObject.variableId,
conversionFactor: 1
}).then(function () {
qmService.hideLoader();
if ($scope.state.fromState) {
goToState($scope.state.fromState, {variableName: $scope.state.userTaggedVariableObject.name});
} else {
qmService.goToDefaultState();
}
});
}
}
$scope.selectVariable = function(selected){
selected = qmService.barcodeScanner.addUpcToVariableObject(selected);
var next = getNextState();
if(!next){
$scope.showVariableActionSheet(selected, [], $scope.state);
return;
}
var s = $state.current;
qmLog.info(s.name + ': ' + '$scope.selectVariable: ' + JSON.stringify(selected).substring(0, 140) + '...', null);
qm.variablesHelper.setLastSelectedAtAndSave(selected);
$scope.state.variableSearchParameters.searchPhrase = '';
if(s.name === 'app.favoriteSearch'){
qmService.addToFavoritesUsingVariableObject(selected);
}else if(window.location.href.indexOf('reminder-search') !== -1){
qmService.reminders.addToRemindersUsingVariableObject(selected, {
skipReminderSettingsIfPossible: $scope.state.skipReminderSettingsIfPossible,
doneState: $scope.state.doneState
});
}else if(next.indexOf('predictor') !== -1){
goToState(next, {effectVariableName: selected.name});
}else if(next.indexOf('outcome') !== -1){
goToState(next, {causeVariableName: selected.name});
}else if($scope.state.userTaggedVariableObject){
saveTag(selected);
}else if($scope.state.userTagVariableObject){
saveTagged(selected);
}else{
$scope.state.variableName = selected.name;
$scope.state.variableObject = selected;
goToState(next, $scope.state);
}
};
$scope.goToStateFromVariableSearch = function(stateName, params){
//if(!params){params = $stateParams;} // This prevents correct variable search params when going to add
// a reminder from the variable search page
var state = qmStates.find(function(s){return s.name === stateName});
if(!params){params = state.params;}
goToState(stateName, params);
};
// when a query is searched in the search box
function showAddVariableButtonIfNecessary(variables){
var barcode = $scope.state.variableSearchParameters.barcode;
if(barcode && barcode === $scope.state.variableSearchParameters.searchPhrase){
$scope.state.showAddVariableButton = false;
return;
}
if($scope.state.doNotShowAddVariableButton){
$scope.state.showAddVariableButton = false;
return;
}
var resultIndex = 0;
var found = false;
while(!found && resultIndex < $scope.state.variableSearchResults.length){
if($scope.state.variableSearchResults[resultIndex].name.toLowerCase() ===
$scope.state.variableSearchParameters.searchPhrase.toLowerCase()){
found = true;
}else{
resultIndex++;
}
}
// If no results or no exact match, show "+ Add [variable]" button for query
if((variables.length < 1 || !found)){
$scope.showSearchLoader = false;
qmLog.info($state.current.name + ': ' + '$scope.onVariableSearch: Set showAddVariableButton to true', null);
$scope.state.showAddVariableButton = true;
var s = $state.current;
var next = s.params.nextState;
var text;
var q = $scope.state.variableSearchParameters.searchPhrase;
if(next === qm.staticData.stateNames.reminderAdd){
text = '+ Add ' + q + ' reminder';
}else if(next === qm.staticData.stateNames.measurementAdd){
text = '+ Add ' + q + ' measurement';
}else{
text = '+ ' + q;
}
$scope.safeApply(function(){
$scope.state.addNewVariableButtonText = text;
})
}
}
function showNoVariablesFoundCardIfNecessary(errorHandler){
if($scope.state.variableSearchResults.length || !$scope.state.doNotShowAddVariableButton){
$scope.state.noVariablesFoundCard.show = false;
return;
}
$scope.state.noVariablesFoundCard.title = $scope.state.variableSearchParameters.searchPhrase + ' Not Found';
if($scope.state.noVariablesFoundCard && $scope.state.noVariablesFoundCard.body){
$scope.state.noVariablesFoundCard.body = $scope.state.noVariablesFoundCard.body.replace(
'__VARIABLE_NAME__', $scope.state.variableSearchParameters.searchPhrase.toUpperCase());
}else{
$scope.state.noVariablesFoundCard.body = "You don't have any data for " +
$scope.state.variableSearchParameters.searchPhrase.toUpperCase() + ", yet. Start tracking!";
}
if(errorHandler){
errorHandler();
}
$scope.state.noVariablesFoundCard.show = true;
}
function variableSearchSuccessHandler(variables, successHandler, errorHandler){
if(successHandler && variables && variables.length){
successHandler();
}
if(errorHandler && (!variables || !variables.length)){
errorHandler();
}
addVariablesToScope(variables);
if(!errorHandler){
$scope.safeApply(function (){
showAddVariableButtonIfNecessary(variables);
})
}
showNoVariablesFoundCardIfNecessary(errorHandler);
}
function addVariablesToScope(variables){
variables = qm.arrayHelper.removeArrayElementsWithDuplicateIds(variables, 'variable');
$scope.safeApply(function(){
$scope.state.noVariablesFoundCard.show = false;
$scope.state.showAddVariableButton = false;
$scope.state.variableSearchResults = variables;
var count = (variables) ? variables.length : 0;
qmLog.info(count + ' variable search results from ' + $scope.state.variableSearchParameters.searchPhrase + " search");
$scope.state.searching = false;
});
}
function hideLoader(){
$scope.safeApply(function(){
$scope.state.searching = false;
});
}
function getVariableSearchParameters(){
// $stateParams.variableSearchParameters.searchPhrase is getting populated somehow and is not being updated
delete $stateParams.variableSearchParameters.searchPhrase;
let params = qm.objectHelper.copyPropertiesFromOneObjectToAnother($scope.state.variableSearchParameters,
$stateParams.variableSearchParameters, false)
params.limit = 10;
return params;
}
$scope.onVariableSearch = function(successHandler, errorHandler){
$scope.state.noVariablesFoundCard.show = false;
$scope.state.showAddVariableButton = false;
var params = getVariableSearchParameters();
var q = $scope.state.variableSearchParameters.searchPhrase;
qmLog.info($state.current.name + ': ' + 'Search term: ' + q + " with params: ", params);
if(q.length > 2){
$scope.state.searching = true;
params.searchPhrase = q;
qm.variablesHelper.getFromLocalStorageOrApi(params).then(function(variables){
variableSearchSuccessHandler(variables, successHandler, errorHandler);
});
}else{
populateSearchResults();
}
};
var populateSearchResults = function(){
var q = $scope.state.variableSearchParameters.searchPhrase;
if(q.length > 2){
return;
}
$scope.state.showAddVariableButton = false;
var previous = $scope.state.variableSearchResults;
if(!previous || previous.length < 1){$scope.state.searching = true;}
var params = getVariableSearchParameters();
$scope.state.searching = true;
qm.variablesHelper.getFromLocalStorageOrApi(params)
.then(function(variables){
qmLog.info("Got "+variables.length+" matching params: ", params)
if(variables && variables.length > 0){
if(q.length < 3){
// Not sure what this is for but it breaks the category filter: if(previous){variables = previous.concat(variables);}
addVariablesToScope(variables);
}
}else{
$scope.state.noVariablesFoundCard.show = true;
}
hideLoader();
})
.catch(function(error){
qmLog.error(error);
hideLoader();
});
};
$scope.addNewVariable = function(){
var variableObject = {};
variableObject = qmService.barcodeScanner.addUpcToVariableObject(variableObject);
variableObject.name = $scope.state.variableSearchParameters.searchPhrase;
if(getVariableCategoryName()){
variableObject.variableCategoryName = getVariableCategoryName();
}
qmLog.info($state.current.name + ': ' + '$scope.addNewVariable: ' + JSON.stringify(variableObject));
$scope.state.variableObject = variableObject;
goToState(getNextState(), $scope.state);
};
function setHelpText(){
if($scope.state.userTaggedVariableObject){
$scope.state.helpText = "Search for a variable like an ingredient, category, or duplicate variable " +
"that you'd like to tag " + $scope.state.userTaggedVariableObject.name.toUpperCase() + " with. Then " +
"when your tag variable is analyzed, measurements from " +
$scope.state.userTaggedVariableObject.name.toUpperCase() + " will be included.";
$scope.state.helpText = "
Search for a variable " +
"that you'd like to tag with " + $scope.state.userTaggedVariableObject.name.toUpperCase() + ". Then " +
"when " + $scope.state.userTaggedVariableObject.name.toUpperCase() +
" is analyzed, measurements from your selected tagged variable will be included.
For instance, if " +
"your currently selected variable were Inflammatory Pain, you could search for and select Back Pain " +
"to be tagged with Inflammatory Pain since Inflammatory Pain includes Back Pain. Then Back Pain " +
"measurements would be included when Inflammatory Pain is analyzed";
}
if($scope.state.userTagVariableObject){
$scope.state.helpText = "Search for a child variable " +
"that you'd like to tag with " + $scope.state.userTagVariableObject.name.toUpperCase() + ". Then " +
"when " + $scope.state.userTagVariableObject.name.toUpperCase() +
" is analyzed, measurements from your selected tagged variable will be included.";
$scope.state.helpText = $scope.state.helpText + "
For instance, if " +
"your currently selected variable were Sugar, you could search for Coke and tag it with 37 grams of " +
"sugar per serving. Then coke measurements would be included when analyzing to see how sugar affects you.
" +
"If your current parent tag variable were Inflammatory Pain, you could search for Back Pain and then your " +
"Inflammatory Pain analysis would include Back Pain measurements as well.";
}
var singularCategoryName = getSingularVariableCategoryName();
if(!$scope.state.helpText && singularCategoryName){
$scope.state.helpText = 'Enter a ' + singularCategoryName.toLowerCase() + ' in the search box or select one from the list below.';
}
if(!$scope.state.helpText){
$scope.state.helpText = 'Enter a variable in the search box or select one from the list below.';
}
}
function getSingularVariableCategoryName(){
var variableCategory = getVariableCategory();
if(variableCategory && variableCategory.variableCategoryNameSingular){
return variableCategory.variableCategoryNameSingular;
}
return null;
}
function getVariableCategory(){
var name = getVariableCategoryName();
if(name){return qm.variableCategoryHelper.findByNameIdObjOrUrl(name);}
return null;
}
function getVariableCategoryName(){
var fromUrl = qm.variableCategoryHelper.getNameFromStateParamsOrUrl();
if(fromUrl){return fromUrl;}
var params = getVariableSearchParameters();
if(params.variableCategoryName){
return params.variableCategoryName;
}
return qm.variableCategoryHelper.getNameFromStateParamsOrUrl($stateParams);
}
function getPluralVariableCategoryName(){
return $filter('wordAliases')(pluralize(getVariableCategoryName(), 1));
}
// https://open.fda.gov/api/reference/ API Key https://open.fda.gov/api/reference/
$scope.scanBarcode = function(){
var params = getVariableSearchParameters();
qmService.barcodeScanner.scanBarcode(params, variableSearchSuccessHandler, function(error){
qmLog.error(error);
});
}
}]);