Zabs
Zabs

Reputation: 14142

error msg - is not a function when using prototype for an Angular service

I am building an Angular service for some re-usable code for an upload named 'UploadService' which gets called within a controller below - even though the service has been loaded in I always get the following error

`UploadService.upload is not a function at h.$scope.uploadImage...)`

My Upload Service (UploadService.js)

abcdServices.service('UploadService', function(ApiService, $http, $localStorage, $location, $timeout, $q, $rootScope, Upload) {

var UploadService = function() {
      this.upload_in_progress = false;
      this.attached_media = {
        photos: [],
        videos: []
      }
  };

  UploadService.prototype.upload = function(files) {
     console.log('get here');

  };

  return UploadService;

});

// My Controller where the service is called - note I have added this to the

    $scope.uploadImage = function(files, fileIndex, imageIndex) {
        console.log('existing upload image');
        console.log(files); // this shows an array in the console log as expected
        UploadService.prototype.upload(files);

    }

// The controller has the service loaded in at the top and I have included UserService.js file in the index.php

abcdControllers.controller('PostController', function( $http, $rootScope, UploadService) {

Upvotes: 0

Views: 144

Answers (1)

lenilsondc
lenilsondc

Reputation: 9800

The prototype is just a javascript way to add instance members to a "Class". The point is, you have to use the UploadService.upload() directly not through the prototype UploadService.prototype.upload() because UploadService is not a reference to the class, angularjs' injector gives you an instance of that class, when you declare a service UploadService, angularjs injects a singleton reference to new UploadService().

Also, you are declaring the service class in the wrong way, your approach doesn't return the UploadService class for the injector, it only returns a function that returns the UploadService, which is never exposed. A better approach for that would be something like the code bellow:

abcdServices.service('UploadService', function UploadService(ApiService, $http, $localStorage, $location, $timeout, $q, $rootScope, Upload) {    
    this.upload_in_progress = false;
    this.attached_media = {
        photos: [],
        videos: []
    };

    this.upload = function(files) {
        console.log('get here');    
    };    
});

Or you can simply change it to a factory provider and return a new instance of your "Class":

abcdServices.factory('UploadService', function(ApiService, $http, $localStorage, $location, $timeout, $q, $rootScope, Upload) {    
  var UploadService = function() {
      this.upload_in_progress = false;
      this.attached_media = {
        photos: [],
        videos: []
      };
  };

  UploadService.prototype.upload = function(files) {
     console.log('get here');    
  };

  return new UploadService();    
});

Upvotes: 1

Related Questions