Fresheyeball
Fresheyeball

Reputation: 30025

Angular services and coffee-script classes

What I would like is to define a static class as a service in angular.

Here is what I would like:

class MyService extends ServiceBase
   @thing  = 'thing'
   @method = -> alert 'I fired'


# neither of these work
angular.module('Foo').service 'MyService', -> MyService
angular.module('Foo').service 'MyService', MyService

# these work but prevent the use of `extends`
angular.module('Foo').service 'MyService', ->
   @thing  = 'thing'
   @method = -> alert 'I fired'

angular.module('Foo').service 'MyService', ->
   thing  : 'thing'
   method : -> alert 'I fired'

myService =
   thing  : 'thing'
   method : -> alert 'I fired'

angular.module('Foo').service 'MyService', -> myService

The error I get when using classes is a type error. Angular wants an Object but all coffee classes are type Function. Is there a way around this?

Please note, this is because I want to use .service NOT .factory. I know how to fix this with .factory already.

Upvotes: 0

Views: 1038

Answers (1)

Ben Lesh
Ben Lesh

Reputation: 108501

Please note, this is because I want to use .service NOT .factory. I know how to fix this with .factory already.

Why? lol.

Okay, anyhow try this:

angular.module('Foo').service 'MyService', -> 
    {
       $get: -> MyService
    }

or this:

angular.module('Foo').service 'MyService', -> $get: -> myService

Edit: responding to comments below...

There is no constructor in my example.

There is, actually:

class MyService extends ServiceBase

MyService is a class constructor function that has a prototype of a new instance of ServiceBase. It's expecting to be called with the new keyword.

The functional equivalent in JavaScript is:

function MyService() {}

MyService.prototype = new ServiceBase();

So you see... constructor function.

So one of the problems you're likely going to run into is the fact you have to create a new instance of your MyService in every controller you pass it to, and each one of those instances is different. You'd be better off using an object literal to carry state, or at the very least creating a new instance of MyService and returning that directly from your service declaration. This is because all angular services are, by default, singletons, meaning it's always going to be the same instance.

Try the following to allow sharing values between two controllers.

angular.module('Foo').service 'storageService' -> $get: -> {}

angular.module('Foo').controller 'SomeCtrl', class SomeCtrl
  constructor: ($scope, storageService) ->
    $scope.storage = storageService
    $scope.storage.i = $scope.storage.i || 0
    $scope.increment = -> $scope.storage.i++

angular.module('Foo').controller 'OtherCtrl', class OtherCtrl
   constructor: ($scope, storageService) ->
     $scope.storage = storageService;     
     $scope.storage.i = $scope.storage.i || 0
     $scope.decrement = -> $scope.storage.i--;

Anyhow, I hope that helps. Happy holidays.

Upvotes: 1

Related Questions