Charles Jackson
Charles Jackson

Reputation: 115

angularjs - using controller promise when calling service function

I have a base controller into which I inject a service called Uom. I call the service from my controller as follows:

Uom.get_measurement_unit_conversions().then( function( measurement_unit_conversions ) {
    // Do some stuff here
});

and my service looks like...

angular.module('uomService', [])

.factory('Uom', function( $http ) {

return {

    /**
     * Will make a call to the restful API to get the 
     * measurement unit conversions and then return the formatted data.
     *
     * @return {float} Converted value
     */
    get_measurement_unit_conversions: function()
    {
        var conversions = {};

        $http({ method: 'GET', url: '/api/measurement_unit_conversions' })
        .then( function( response ) {

            angular.forEach( response.data.measurement_unit_conversions, function( object, key ) {

                if( conversions.hasOwnProperty( object.source_measurement_unit_id ) == false )
                {
                    conversions[object.source_measurement_unit_id] = {};
                }

                conversions[object.source_measurement_unit_id][object.target_measurement_unit_id] = object.formula;
            });

            return conversions;
        });
    }
}
});

but I keep getting the error

Uom.get_measurement_unit_conversions(...).then is not a function

I took my approach from another stack overflow question

What is the best practice for making an AJAX call in Angular.js?

Any idea what I am doing wrong?

Upvotes: 0

Views: 715

Answers (2)

Dan Cohen
Dan Cohen

Reputation: 151

There are a couple issues here - first of all, note that your get_measurement_unit_conversions function is not actually returning anything. The return statement is in a then block, but the service function itself is returning undefined. As Charles says, you must return the result from $http(...).

The other issue is that in order for 'promise chaining' to work, you need to return a promise from your then function.

Here is a modified version of the service that should work (beware, untested). Note that I inject the $q service, for use of $q.when() which wraps arbitrary values in a new promise:

angular.module('uomService', [])
.factory('Uom', function( $http, $q ) {

    return {

    /**
     * Will make a call to the restful API to get the 
     * measurement unit conversions and then return the formatted data.
     *
     * @return {float} Converted value
     */
    get_measurement_unit_conversions: function()
    {
        return $http({ method: 'GET', url: '/api/measurement_unit_conversions' })
        .then( function( response ) {
            var conversions = {};
            angular.forEach( response.data.measurement_unit_conversions, function( object, key ) {

                if( conversions.hasOwnProperty( object.source_measurement_unit_id ) == false )
                {
                    conversions[object.source_measurement_unit_id] = {};
                }

                conversions[object.source_measurement_unit_id][object.target_measurement_unit_id] = object.formula;
            });
            return $q.when(conversions);
        });
    }
}
});

Upvotes: 1

theleebriggs
theleebriggs

Reputation: 571

You have to return the $http call as this returns a promise.

return $http(...)

Upvotes: 0

Related Questions