Ryan.lay
Ryan.lay

Reputation: 1761

Angularjs service typerror undefined is not a function

I have a service in coffeescript like so:

App.service 'CalculateService', ->
  @Calculate = (student) ->
    if student.type == 'MatureStudent'
      student.age + 10
    else
      student.age + 5

JS version

App.service('CalculateService', function() {
  return this.Calculate = function(student) {
    if (student.type === 'MatureStudent') {
      return student.age + 10;
    } else {
      return student.age + 5;
    }
  };
});

And a controller like so:

App.controller 'MarksCtrl', ($scope, $filter, CalculateService, lecture) ->

**create array**
$scope.students = []
angular.forEach $scope.lecture.students, (student) ->
    ......
  $scope.students.push(student)

**save array**
$scope.saveStudents = ->
    angular.forEach $scope.students, (student) ->
        student.points = CalculateService.Calculate(student)

JS version

App.controller('MarksCtrl', function($scope, $filter, CalculateService, lecture) {
  $scope.students = [];
  angular.forEach($scope.lecture.students, function(student) {
    return $scope.students.push(student);
  });
  return $scope.saveStudents = function() {
    return angular.forEach($scope.students, function(student) {
      return student.points = CalculateService.Calculate(student);
    });
  };
});

I keep getting "Typeerror undefined is not a function" at when I call the CalculateService.Calculate and I have no idea why.

I've tried this and it works:

$scope.saveStudents = ->
  angular.forEach $scope.students, (student) ->
    student.points = 2

So the problem only arises when I call the service. Any idea how I can make this work?

Upvotes: 0

Views: 256

Answers (2)

PSL
PSL

Reputation: 123739

It looks like you are returning the function itself as service. Instead just do not return the function, service gets newed up by the injector just attach the method to its instance and return nothing. In your original case you would have to invoke it as CalculateService(student)

Try:

App.service 'CalculateService', ->

  @Calculate = (student) ->
    if student.type == 'MatureStudent'
      student.age + 10
    else
      student.age + 5

  return

I have not used coffeescript, i used this transpiler to figure out what your service definition actually is. In times of doubts like these do a console logging of the service to see what it actually outputs (in your case you should see the function itself).

Upvotes: 3

rmuller
rmuller

Reputation: 1837

Considering CoffeeScript automatically returns the last line of code, it is necessary to place a return statement at the bottom of the service

app.service 'CalculateService', ->
  @Calculate = (student) ->
    if student.type == 'MatureStudent'
      student.age + 10 
    else
      student.age + 5  

return

Plunkr

Upvotes: 1

Related Questions