0

I have a hard time initialising a new resource object.

Retrieving data from the REST API works just fine.

The error gets thrown at the following line of code:

var newRoom = new this.lobbyStorage.LobbyRoom();

with the following message:

"this.$ngResource is not a function"

I'd been trying quite a few things but nothing which lead me to a positive result.

Solution

Functions created with the syntax new Function(...) or just Function(...) have their name property set to an empty string. In the following examples anonymous functions are created, so name returns an empty string:

You cannot change the name of a function, this property is read-only:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name


lobby-storage.ts

module lobby.services {
  export class LobbyStorage {

    private baseUrl : string = 'http://localhost:2999'; /*this.appConstant.baseUrl + '/lobby';*/

    public static $inject = [
      '$http',
      '$resource'
    ];

    constructor(private $http: ng.IHttpService, private $ngResource : ng.resource.IResourceService /*,private appConstant*/) {

    }

    public LobbyRoom() : ng.resource.IResourceClass<ng.resource.IResource<any>> {
      return this.$ngResource(this.baseUrl + '/lobby/:id', { id: '@id' });
    }
  }
}

lobby-modules.ts

///<reference path='../../typings/tsd.d.ts' />
module lobby {
  'use strict';

  /* @ngdoc object
   * @name lobby
   * @description
   *
   */
  angular
    .module('lobby', [
      'ngRoute',
      'ngResource'
    ])
    .service('lobbyStorage', lobby.services.LobbyStorage)
  /* .constant('appConstant', lobby.constants.Constants.Default);*/
}

lobby-controller.ts

/// <reference path='../_lobby.ts' />

module lobby.controllers {
  'use strict';

  class LobbyCtrl {

    public lobbyData : Array<string>;
    public gameCreation : boolean = true;
    public currentItem : any = {};

    // $inject annotation.
    // It provides $injector with information about dependencies to be injected into constructor
    // it is better to have it close to the constructor, because the parameters must match in count and type.
    // See http://docs.angularjs.org/guide/di
    public static $inject = [
      '$scope',
      '$log',
      'lobbyStorage'
    ];

    // dependencies are injected via AngularJS $injector
    constructor(private $scope, private $log : ng.ILogService, private lobbyStorage) {
      this.init();
    }

    // Initializer function
    private init(){
      this.initializeLobbyData();
    }

    public createRoom() : void{
      var newRoom = new this.lobbyStorage.LobbyRoom();
      newRoom.name = this.currentItem.name;
      newRoom.$save();
    }

    public initializeLobbyData(){
      var res = this.lobbyStorage.LobbyRoom().query(
        () => this.lobbyData = res,
        () => this.lobbyData[0] = "Error"
      );
    }
  }


  /**
  * @ngdoc object
  * @name lobby.controller:LobbyCtrl
  *
  * @description
  *
  */
  angular
    .module('lobby')
    .controller('LobbyCtrl', LobbyCtrl);
}
HansMusterWhatElse
  • 671
  • 1
  • 13
  • 34

2 Answers2

1

When you call LobbyRoom with 'new' it is intended that you are creating a new object. The 'this' LobbyRoom uses will be of the new object you are creating and will not refer to the class. You should do either one of two things. Either create a LobbyRoom class or call LobbyRoom without using 'new' like so:

var newRoom = this.lobbyStorage.LobbyRoom();
WillSeitz
  • 75
  • 1
  • 2
1

The point here is that we call a function not constructor

// wrong
// this is not constructor call
var newRoom = new this.lobbyStorage.LobbyRoom()

// ok
// just a method
var newRoom = this.lobbyStorage.LobbyRoom()

There is a broken example (just click run)

var x = new lobby.services.LobbyStorage({}, (str) => {return str});

try {
  var y = new x.LobbyRoom();
}
catch (ex){
  alert(ex);    
}

If we would not call it as constructor, but as the method - it will work:

var x = new lobby.services.LobbyStorage({}, (str) => {return str});

var y =  x.LobbyRoom();

alert(y);

check that version here

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Thanks for the hint, didn't quite pay attention to that - at one point I was beyond that point and got an error one line further when I tried to assign something to the resource object. `newRoom.name = this.currentItem.name` resulted in => TypeError: Cannot assign to read only property 'name' of function Resource(value) { shallowClearAndCopy(value || {}, this); } – HansMusterWhatElse Aug 06 '15 at 15:28