Q: v2.canGoForward is not a function I am trying to move the code vm.canGoForward from my controller to a service to hide the implementation details.
BEFORE CODE CHANGE
This worked fine.
View:
<button ng-disabled="!vm.canGoForward()" class="btn btn-primary" name="next" type="button" ng-click="vm.gotoStep(vm.currentStep + 1)">

Controller:
var vm = this;
vm.currentStep = 1;
vm.steps = WizardService.getWizardSteps(vm.formData);

vm.canGoForward = function() {
  var res = true,
  i,
  nextStateIndex = vm.currentStep + 1;

  if (nextStateIndex > vm.steps.length) {
    return false;
  }
  for (i = 1; res && i <= nextStateIndex; i++) {
    res = (res && vm.steps[i-1].isReady());
  }

  return !!res;
};

Service
var wizardService = {
  getWizardSteps: getWizardSteps
};
return wizardService;

function getWizardSteps(formData) {
  var wizardSteps = [
    {
      step: 1,
      name: 'Name',
      template: 'views/wizard/step1.html',
      isReady: function() { return true; }
    },
    {
      step: 2,
      name: 'Email',
      template: 'views/wizard/step2.html',
      isReady: function() { return formData.firstName && formData.lastName; }
    },
    {
      step: 3,
      name: 'Job Category',
      template: 'views/wizard/step3.html',
      isReady: function() { return formData.email; }
    }
  ];
  return wizardSteps;
}

AFTER CODE CHANGE
View
Remains the same
Controller
var vm = this;
vm.currentStep = 1;
vm.steps = WizardService.getWizardSteps(vm.formData);
vm.canGoForward = WizardService.canGoForward(vm.currentStep, vm.steps);

Service
var wizardService = {
  getWizardSteps: getWizardSteps,
  canGoForward: canGoForward
};
return wizardService;

function getWizardSteps(formData) {
  var wizardSteps = [
    {
      step: 1,
      name: 'Name',
      template: 'views/wizard/step1.html',
      isReady: function() { return true; }
    },
    {
      step: 2,
      name: 'Email',
      template: 'views/wizard/step2.html',
      isReady: function() { return formData.firstName && formData.lastName;  }
    },
    {
      step: 3,
      name: 'Job Category',
      template: 'views/wizard/step3.html',
      isReady: function() { return formData.email; }
    }
  ];
  return wizardSteps;
}

function canGoForward(currentStep, steps) {
  console.log(steps);

  var res = true,
  i,
  nextStateIndex = currentStep + 1;

  if (nextStateIndex > steps.length) {
    return false;
  }
  for (i = 1; res && i <= nextStateIndex; i++) {
    res = (res && steps[i-1].isReady());
  }

  return !!res;
}

I now get the following error: TypeError: v2.canGoForward is not a function. How can I resolve it?

A: In your second version, the following line will actually call WizardService.canGoForward on the spot, not assign it:
vm.canGoForward = WizardService.canGoForward(vm.currentStep, vm.steps);

What gets assigned is the return value of that call, which obviously is not a function, hence the error message when a call is attempted later.
If you want to assign the function, and ensure the arguments get passed when it is called later, then use bind:
vm.canGoForward = WizardService.canGoForward.bind(WizardService, vm.currentStep, vm.steps);

