1

Fairly new to angular so I think I'm missing something simple. I have a function that I need to call from both a view and within the controller. From the view I give the option to continue or start over so I have two functions declared as below. both buttons in the view work fine this way.

$scope.start_new = function(){
//logic in here
}

$scope.continue_work = function(){
//logic in here
}

My problem is if it's the first time through I don't want to give the option so I have

//if the variable doesn't exist run the init
if(angular.isUndefined($localStorage.testVar)){
    //I've tried these ways
    //start_new();
    //$scope.start_new;
    //$scope.start_new();
}
else{
    $scope.active = false; //disply the layer which gives the choice
}

none of these fire the function. If I declare it like this:

function start_new(){
//logic in here
}

it runs fine on the controller load but the button in the view no longer works. The button code looks like this:

<button type="button" ng-click="start_new()" class="btn btn-info btn-lg btn200">Start New</button>

Any help would be greatly appreciated!!

here is the actual code:

stControllers.controller('WorkoutCtrl',['$scope','$routeParams','$localStorage','$filter','$location','Flash',function ($scope,$routeParams,$localStorage,$filter,$location,Flash) {

//set up counter background
$scope.strokeWidth = 20;
$scope.stroke = '#71d2f3';
$scope.background = '#eee';
$scope.size = 205;

$scope.show_list = false;
$scope.active = true;
if(angular.isUndefined($localStorage.currentWorkout)){
    //set up current workout

    $scope.start_workout();
}
else{
    $scope.active = false;

}


$scope.start_workout = function(){
    $scope.active = true;
    $scope.currentWorkout = $localStorage.userProgramTemplate[$routeParams['day_id']];
    $scope.setCount = $localStorage.setCounterTotal[$routeParams['day_id']];
    $localStorage.currentWorkout = $localStorage.userProgramTemplate[$routeParams['day_id']];

    //set up the workout detail
    $scope.workoutName = $localStorage.userProgramDay[$routeParams['day_id']]['program_day_name'];
    $scope.workoutDate = new Date();

    //workout progress circle
    $scope.currentSet = 1

    $scope.progress = $scope.currentSet/$scope.setCount;

    //start at first group
    $scope.workoutIndex = 0;
    $scope.groupCounter = 0;

    //start at first exercise
    $scope.exerciseIndex = 0;
    $scope.currentExerciseSet = 1;


    $scope.exerciseCounter = {};
    $scope.currentExercise = $scope.currentWorkout[$scope.workoutIndex][$scope.exerciseIndex];
    $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id] = {};
    $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id] = 1;
    $scope.currentExerciseSet = $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id];

    $scope.setProgress = ($scope.currentExerciseSet/$scope.currentExercise.sets) * 100;

    //reps
    $scope.reps = parseInt($scope.currentExercise.reps);
    //weight
    $scope.weight = parseInt($scope.currentExercise.weight);

    //create a storage variable to store counters in
    $localStorage.counters = {};
    $localStorage.counters['setCount'] = $scope.setCount;
    $localStorage.counters['workoutDate'] = $scope.workoutDate;
    $localStorage.counters['workoutName'] = $scope.workoutName;
    $localStorage.counters['exerciseIndex'] = $scope.exerciseIndex
$localStorage.counters['currentSet'] = $scope.currentSet;
$localStorage.counters['groupCounter'] = $scope.groupCounter;
$localStorage.counters['workoutIndex'] = $scope.workoutIndex;
$localStorage.counters['exerciseCounter'] = $scope.exerciseCounter;

list();

}

$scope.continue_workout = function(){
    $scope.active = true;

$scope.currentWorkout = $localStorage.currentWorkout;
    //set these values  
    $scope.setCount = $localStorage.counters['setCount'];
$scope.workoutDate = $localStorage.counters['workoutDate'];
    $scope.workoutName = $localStorage.counters['workoutName'];
$scope.exerciseIndex = $localStorage.counters['exerciseIndex'];//storage
$scope.currentSet = $localStorage.counters['currentSet'];//storage
$scope.groupCounter = $localStorage.counters['groupCounter'];//storage
$scope.workoutIndex = $localStorage.counters['workoutIndex'];//storage
$scope.exerciseCounter = $localStorage.counters['exerciseCounter'];//storage




$scope.currentExercise = $scope.currentWorkout[$scope.workoutIndex][$scope.exerciseIndex];


if(angular.isUndefined($scope.exerciseCounter[$scope.currentExercise.user_workout_group_id])){
    $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id] = {};
}

if(angular.isUndefined($scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id])){
    $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id] = 0;
}


$scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id] = $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id];// + 1;

$scope.currentExerciseSet = $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id];


//increment the progress bars
$scope.setProgress = ($scope.currentExerciseSet/$scope.currentExercise.sets) * 100;
$scope.progress = $scope.currentSet/$scope.setCount;


    //set the projected reps and weight     
$scope.reps = parseInt($scope.currentExercise.reps);
    $scope.weight = parseInt($scope.currentExercise.weight);

list();

}

$scope.next = function(){


//record the prvious info
$localStorage.currentWorkout[$scope.workoutIndex][$scope.exerciseIndex]['reps'] = $scope.reps;
$localStorage.currentWorkout[$scope.workoutIndex][$scope.exerciseIndex]['weight'] = $scope.weight;
$localStorage.currentWorkout[$scope.workoutIndex][$scope.exerciseIndex]['date'] = $filter('date')(new Date(), "yyyy-MM-dd HH:mm:ss");
$localStorage.currentWorkout[$scope.workoutIndex][$scope.exerciseIndex]['set'] = $scope.currentExerciseSet;

    //increment the counters
$scope.exerciseIndex++;
$scope.currentSet++;
$scope.groupCounter++;

    //check for end of set
if($scope.currentWorkout[$scope.workoutIndex].length <= $scope.groupCounter){
    $scope.groupCounter = 0;
    $scope.exerciseIndex = 0;
        $scope.currentExerciseSet = 1;
    $scope.workoutIndex++;

    //check if it's the end of the workout
    if($scope.currentWorkout.length <= $scope.workoutIndex){
        var message = '<strong> Workour complete</strong>';
        Flash.create('success', message, 'custom-class');

        if(angular.isUndefined($localStorage.history)){
            $localStorage.history = [];
        }
        $localStorage.history.push($scope.currentWorkout);
        delete $scope.currentWorkout;
        delete $localStorage.currentWorkout;
        delete $localStorage.counters;
        //move workout into history and unset current workout variable

        $location.path('/home');    

    }
}

$scope.currentExercise = $scope.currentWorkout[$scope.workoutIndex][$scope.exerciseIndex];


if(angular.isUndefined($scope.exerciseCounter[$scope.currentExercise.user_workout_group_id])){
    $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id] = {};
}

if(angular.isUndefined($scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id])){
    $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id] = 0;
}

$scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id] = $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id] + 1;


//set up exercise progess   
$scope.currentExerciseSet = $scope.exerciseCounter[$scope.currentExercise.user_workout_group_id][$scope.currentExercise.exercise_id];

//increment the progress bars
$scope.setProgress = ($scope.currentExerciseSet/$scope.currentExercise.sets) * 100;
$scope.progress = $scope.currentSet/$scope.setCount;

    //set the projected reps and weight     
$scope.reps = parseInt($scope.currentExercise.reps);
    $scope.weight = parseInt($scope.currentExercise.weight);

    //set up some variable in local storage to use if we resume a workout
    $localStorage.counters['exerciseIndex'] = $scope.exerciseIndex;;
$localStorage.counters['currentSet'] = $scope.currentSet;
$localStorage.counters['groupCounter'] = $scope.groupCounter;
$localStorage.counters['workoutIndex'] = $scope.workoutIndex;
$localStorage.counters['exerciseCounter'] = $scope.exerciseCounter;

}

function list(){
$scope.workout_list = $localStorage.userProgramDay[$localStorage.counters['workoutIndex']];

//console.log($scope.workout_list)

}

}]);

Markus
  • 45
  • 9
  • 1
    Your third commented out example should work. What makes you think it doesn't? Does the code even get to that point? Can you show an example of this not working? – Matthew Green Sep 24 '15 at 21:40
  • That's what I thought but I get: TypeError: $scope.start_new is not a function – Markus Sep 24 '15 at 21:52

1 Answers1

0
$scope.start_new = function(){
//logic in here
}

and then

//if the variable doesn't exist run the init
if(angular.isUndefined($localStorage.testVar)){
    $scope.start_new();
}
else {
    $scope.active = false; //display the layer which gives the choice
}

is correct. I can't see exactly what is going on in your code, but I suspect you are calling the function just fine -- you just have some sort of race condition causing it to not work as expected.

Try putting a console.log() in your function to see if it is being hit when you expect it to be hit.

EDIT:

I'm pretty sure this is happening because you are using start_workout() (line 14) before it is defined (line 22). Try moving the function declaration above the //set counter background and the original suggested solution should work.

Typically JS evaluates statements in a top-down fashion; there is a concept known as variable hoisting that causes straight up function a(){} calls to be evaluated immediately -- effectively hoisting them to the top of the code block. This is why the function works fine when you declare it as a free standing function rather than attaching it to $scope.

You can find more information in this SO answer: https://stackoverflow.com/a/261682/2457037

Community
  • 1
  • 1
clocklear
  • 43
  • 6
  • I do have one In there, it doesn't get hit. I will post the full code in the am as I'm not at my computer at the moment. As I said above I get the type error but I really can't see anything wrong. I'll post the actual code (was trying to keep it clean). And hopefully you guys can take another look. Thanks! – Markus Sep 24 '15 at 23:12
  • Edited my original response to indicate what I _think_ is happening. – clocklear Sep 25 '15 at 15:09