3

This is module

(function(){

    /**
    * app Module
    *
    * Description
    */
    angular.module('app',[]);
})();

I have this service

(function(){
    'use strict';

angular
    .module('app')
    .factory('homeservice',homeservice);

homeservice.$inject = ['$http']

function homeservice($http){

    var service = {
        test : test
    }
    return service;

    /**
     * get articles
     * @return {[type]} [description]
     */
    function test(){
      $http.get('/test')
         .then(testSuccess)
         .catch(testError)

      function testSuccess(response){
         return response.data;
         //console.log(response.data) this line prints data to console
      }

      function testError(error){
         return error;
      }
    }
}
})();

This is my controller which calls function

(function(){


angular.module('app')
       .controller('HomeController',HomeController);

    HomeController.$inject = ['homeservice']
    function HomeController(homeservice) {
        var vm = this;

        test();

        function test(){
             homeservice.test().then(function(response){
                console.log(response);
            });
        }

    }
    })();

I keep getting the error - Cannot read property 'then' of undefined when I call a method in my controller. I have used this way before and It works properly.

ANSWER

function test(){
          return $http.get('/test') // return was missing here
             .then(testSuccess)
             .catch(testError)

          function testSuccess(response){
             return response.data;
             //console.log(response.data) this line prints data to console
          }

          function testError(error){
             return error;
          }
        }

I was missing return at $http.get('/test')

2
  • did you defined the module? Commented Dec 24, 2016 at 15:19
  • @Sajeetharan yes the module is defined , forgot to add it. Commented Dec 24, 2016 at 15:20

4 Answers 4

4

This

homeservice.test().then(function(response){ ... });

presumes that test method should return a promise. And it returns undefined, that's what the error says.

It should be

/**
 * get articles
 * @return {[type]} [description]
 */
function test(){
  return $http.get('/test')
     .then(testSuccess)
     .catch(testError)

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

2 Comments

When I console.log response from factory , it outputs data to console. But controller throws error .
Not sure what you mean. The code in the question misses return statement, that's why you get Cannot read property 'then' of undefined error. If you're continuing to get the error after applying this answer, please, provide a plunk, so the problem could be replicated.
1

The test function needs to return the $http promise:

function test(){
  ͟r͟e͟t͟u͟r͟n͟  $http.get('/test')
//^^^^^^ ---------------------RETURN the $http promise
     .then(testSuccess)
     .catch(testError)

  function testSuccess(response){
     return response.data;
  }

  function testError(error){
     ̶r̶e̶t̶u̶r̶n̶ ̶e̶r̶r̶o̶r̶;̶
     //throw to chain rejection
     throw error;
  }
}

The return statements in the success and error handlers do not return values to the parent function. Put return statements at each level of the hierarchy.


Rejection re-throw for older versions of AngularJS

Previously (versions <1.6), an error thrown from a promise's onFulfilled or onRejection handlers would also be passed to the $exceptionHandler() (in addition to rejecting the promise with the error as reason).

To avoid an error message in the console with older versions, re-throw by returning a rejected promise:

  function onRejection(error){
     ̶r̶e̶t̶u̶r̶n̶ ̶e̶r̶r̶o̶r̶;̶
     console.log(error.status);
     //throw to chain rejection
     return $q.reject(error);
  }

A common problem for novice programmers is rejected promises getting erroneously converted to fulfilled promises. It is important to re-throw errors from a rejection handler.

Also when a function omit a return statement, that function returns a value of undefined which erroneously converts a rejection to a fulfilled promise that resolves to a value of undefined.

From the Docs:

Due to e13eea, an error thrown from a promise's onFulfilled or onRejection handlers is treated exactly the same as a regular rejection. Previously, it would also be passed to the $exceptionHandler() (in addition to rejecting the promise with the error as reason).

— AngularJS Developer Guide - Migrating to v1.6 ($q)

Comments

0

Shouldn't it be:

$http.get('/test')
  .success(successFunction)
  .error(errorFunction);

At least, that's for versions < 1.4.8

For versions > 1.4.8 try this:

$http.get('/test')
  .then(
    function(response) { }, // success
    function(response) { } // failure
  );

4 Comments

I am using AngularJs version 1.6.0 , but even if i try this it throws another error : $http.get(...).success is not a function
I changed it to include the syntax for > 1.4.8 see if that changes anything.
That does not fix my problem since my logic is the same .
No, it shouldn't. success was deprecated long before 1.4.8.
0
(function(){
    'use strict';

angular
    .module('app')
    .factory('homeservice',homeservice);

homeservice.$inject = ['$http']

function homeservice($http){
   return {
        test: function () {
            console.log("inside function");
            return $http.get('stats.json');
        }
    };
}
})();

DEMO

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.