Josh
Josh

Reputation: 1474

Angular service causing an error

I'm trying to receive data using $http as a dependency injection, then assign that data to a promise using angular's $q service. I'm doing something wrong.. can't seem to locate where.

Service:

myApp.factory('githubApi', ['$http', '$q',
    function($http, $q) {
        var deferred = $q.defer();
        //Declaring a promise that will or will not return a users github information.
        this.accountInformation = function (){
            return $http.get('https://api.github.com/users/joshspears3')
            .then(function(response){
                deferred.resolve(response);
                return deferred.promise;
            }, function(response){
                deferred.reject(response);
                return deferred.promise;
            })
        }
    }
]);

Controller:

myApp.controller('githubCtrl', [ 'githubApi', '$q', '$scope',
    function(githubApi, $q, $scope){
        githubApi.accountInformation()
        .then(
            function (result) {
                $scope.data = result;
            }, function (error) {
                // handle errors here
                console.log(error.statusText);
            }
        );
    }
]);

Directive:

myApp.directive('githubRequest', [
    function() {
        return {
            scope: {},
            restrict: 'E',
            controller: 'githubCtrl',
            templateUrl: 'public/views/partials/github-request.html'
        }
    }
]);

Partial (github-request.html):

<p class="component-example-header">Creating a service. Making a $http request to grab my personal Github information.</p>
<div class="service-message">
    <p>Avatar:</p>
    <img width="20%" src="{{data.avatar_url}}" alt="" />
    <p>Username: <span ng-bind="data.login"></span></p>
    <p>Followers: <span ng-bind="data.followers"></span>, Following: <span ng-bind="data.following"></span></p>
</div>
<hr>

This is the error that the browser is throwing:

Error: [$injector:undef] http://errors.angularjs.org/1.4.4/$injector/undef?p0=githubApi
    at Error (native)
    at http://localhost:9999/bower_components/angular/angular.min.js:6:416
    at Object.$get (http://localhost:9999/bower_components/angular/angular.min.js:37:32)
    at Object.e [as invoke] (http://localhost:9999/bower_components/angular/angular.min.js:39:96)
    at http://localhost:9999/bower_components/angular/angular.min.js:40:410
    at d (http://localhost:9999/bower_components/angular/angular.min.js:38:308)
    at Object.e [as invoke] (http://localhost:9999/bower_components/angular/angular.min.js:39:64)
    at Q.instance (http://localhost:9999/bower_components/angular/angular.min.js:80:151)
    at K (http://localhost:9999/bower_components/angular/angular.min.js:61:140)
    at http://localhost:9999/bower_components/angular/angular.min.js:68:475

It's saying that my githubApi service is undefined when I inject it into my dependencies for possibly my controller?

Upvotes: 2

Views: 104

Answers (3)

Brandon Brooks
Brandon Brooks

Reputation: 271

First, $http.get returns a $q promise already, there is no need to wrap it in a promise again.

Second, a factory creates a single instance of a service which is shared. Therefore the method for the factory should return that object. Assigning anything to this within the factory function itself will not expose that method / property:

myApp.factory('githubApi', ['$http', function ($http) {
    var githubApi = {
      accountInformation: function () {
          return $http.get('https://api.github.com/users/joshspears3');
      }
    };
    return githubApi;
}

Upvotes: 2

taxicala
taxicala

Reputation: 21769

You should be returning the promise in your service method instead, and the deferred object should be inside the method, also, the service should return an object:

myApp.factory('githubApi', ['$http', '$q',
    function($http, $q) {
        //Declaring a promise that will or will not return a users github information.
        return {
            accountInformation: function () {
                var deferred = $q.defer();
                $http.get('https://api.github.com/users/joshspears3')
                    .then(function(response){
                        deferred.resolve(response);
                    }, function(response){
                        deferred.reject(response);
                    });
                return deferred.promise;
            }
        }
    }
]);

You can also simplify this as the $http service already returns a promise:

myApp.factory('githubApi', ['$http',
    function($http) {
        //Declaring a promise that will or will not return a users github information.
        return {
            accountInformation: function () {
                return $http.get('https://api.github.com/users/joshspears3');
            }
        }
    }
]);

Upvotes: 2

Charlie Wynn
Charlie Wynn

Reputation: 933

I think it's because your factory isn't returning anything

myApp.factory('githubApi', ['$http', '$q',
    function($http, $q) {
       return {
          accountInformation: function (){
            var deferred = $q.defer();
            $http.get('https://api.github.com/users/joshspears3')
            .then(function(response){
                deferred.resolve(response);
            }, function(response){
                deferred.reject(response);
            })
            return deferred.promise;
          }
       }
    }
]);

is how I usually have mine

Upvotes: 4

Related Questions