0

I am using Angularjs and typescript to outsource some REST-Methods to a factory. This factory should be used by different controllers. So I have a simple webpage, a controller and a factory I would like to use:

Here is the code for the controller:

/// <reference path="../scripts/typescript/angular.d.ts" />
/// <reference path="../scripts/app.ts" />
/// <reference path="ServiceHttp.ts" />
module nawApp {
   export interface IStundentScope extends ng.IScope {
      fullname: string;
   }
   export class StudentUse {
      private ServiceHttp: any;
      constructor($scope: IStundentScope, ServiceHttp: nawApp.ServiceHttp, $http: ng.IHttpService) {
         this.ServiceHttp = ServiceHttp;
         $scope.fullname = ServiceHttp.exampleFunction();
      }

   }
   StudentUse.$inject = ['$scope', 'ServiceHttp', '$http'];
   nawApp.app.controller('StudentUse', StudentUse);
}

And here is my factory:

/// <reference path="../scripts/typescript/angular.d.ts" />
/// <reference path="../scripts/app.ts" />
module nawApp {
   export class ServiceHttp {
      private http: any;
      constructor(public  $http: any) {
         this.http = $http;
     }
      public exampleFunction():string {
         this.http.get(mainUrl.toString() + 'EventLog').success(function (data, status, headers, config) {
            try {
               return data;
            }
            catch (err) {
               return "Hello Error";
            }
         }).error(function (data, status, headers, config) {
               return "Hello Error 2";
            });
         return "Hello Error 3";
      }
      static Factory($http: ng.IHttpService) {
         return new ServiceHttp($http);
      }
   }
   ServiceHttp.$inject = ['$http'];
   nawApp.app.factory('ServiceHttp', nawApp.ServiceHttp.Factory);
}

I debugged the code and the Factory($http: ng.IHttpService)... part is executed by using ServiceHttp.exampleFunction(), but the string Hello Error 3 is returned and not the return data; part. If I just copy the HTTP.Get stuff to my controller, everything is fine. I think there is a problem with the way I call the factory.

Can You help me? Thanks!!!

1
  • with $http you don't need a deferred Commented Aug 18, 2014 at 13:06

2 Answers 2

1

You could actually just return the chained response from $http:

module nawApp
{
    export class ServiceHttp
    {
        private http: any;
        constructor(public $http: ng.IHttpService, public $q: ng.IQService){
            this.http = $http;
        }
        public exampleFunction(): ng.IPromise<string>{

            return this.http.get(mainUrl.toString() + 'EventLog').success(function (data, status, headers, config){
                return data.SomeStringProperty;
            }).error(function (data, status, headers, config){
                throw new Error('Custom error message');
            });
        }

        static Factory($http: ng.IHttpService){
            return new ServiceHttp($http);
        }
    }
    ServiceHttp.$inject = ['$http', '$q'];
    nawApp.app.factory('ServiceHttp', nawApp.ServiceHttp.Factory);
}

Note that use deferred needlessly is a bad pattern : https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern

Sign up to request clarification or add additional context in comments.

2 Comments

Really interesting link! And a + for your, because that is really surprising anti pattern, really interesting...
You can also replace ServiceHttp.$inject with static $inject property inside the class and replace function (data, status, headers, config) with arrow functions (better, typed arrow functions)
0

You must return a promise from your exampleFunction function instead of a string. Then depending on result of the HTTP call, you either resolve or reject the promise. Key is the return value of your function which should be ng.IPromise<string>. Also note that you can used type ng.IHttpService for the $http service instead of just any.

The service could look like then:

module nawApp
{
    export class ServiceHttp
    {
        private http: any;
        constructor(public $http: ng.IHttpService){
            this.http = $http;
        }
        public exampleFunction(): ng.IPromise<string>{

            return this.http.get(mainUrl.toString() + 'EventLog').success(function (data, status, headers, config){
               return data;
            }).error(function (data, status, headers, config){
               throw new Error("Error");
            });
        }

        static Factory($http: ng.IHttpService){
            return new ServiceHttp($http);
        }
    }
    ServiceHttp.$inject = ['$http'];
    nawApp.app.factory('ServiceHttp', nawApp.ServiceHttp.Factory);
}

Consuming the method is a little different too then. It could look like this:

serviceHttp.exampleFunction()    
    .then(function (result) {
        console.log(result);        
      }, function() {
        console.log("error");
      });       
    };

You can read more about the promises here: https://docs.angularjs.org/api/ng/service/$q

1 Comment

Shouldn't use a deferred when you already have a promise chain going : github.com/petkaantonov/bluebird/wiki/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.