DaveC426913
DaveC426913

Reputation: 2046

angular promises and service

I just can't get my head around promises. Conceptually I get what they're doing I just don't know how to write it (or, at least, debug it).

MyController.js

(function() {
    angular.module('WizmoApp').controller('StoreController', storeController);
    storeController.$inject = ['$scope', '$http', '$q', '$window', 'MyService', 'toastr'];
    function storeController($scope, $http, $q, $window, MyService, toastr) {

    StoreService.getStores().then(
        function(response) {
            console.log(response);
        },
        function(response) {
            toastr.error(response);
        });
    }
})();

As far as I can tell, that is the format for a promise.

MyService.js

(function() {
    angular
    .module('WizmoApp')
    .service('StoreService', storeService);
    storeService.$inject = ['$http', '$q', 'ngAuthSettings'];

    function storeService($http, $q, ngAuthSettings) {

        this.getStores = function() {
            $.getJSON('Content/data/Stores.json', function (json) {
                            return json;
            });
    };
})();

The error I get is

StoreService.getStores(...).then is not a function

Upvotes: 1

Views: 50

Answers (3)

DaveC426913
DaveC426913

Reputation: 2046

I did not think this was relevant - I thought it would just complicate my question but it seems to be closely tied. The purpose of the service is to allow me to flip back and forth between "canned" json data and live api data.

See the dataSource variable used in the switch:

storeController.js

StoreService.getStores().then(function(response) {
    vm.stores = response.data;
}, function(response) {
    toastr.error(response);
 });

storeService.js

(function() {
    'use strict';

    angular
        .module('WizmoApp')
        .service('StoreService', storeService);

    storeService.$inject = ['$http', '$q', 'ngAuthSettings'];

    function storeService($http, $q, ngAuthSettings) {

       var dataSource = 'api';// local or api

        this.getStores = function() {

            return $q (function(resolve, reject) {
                switch (dataSource) {
                    case 'api'://staging - live api data
                        $http({
                            method: 'get',
                            url: serviceBase + 'api/Stores'
                        }).then(function(results) {
                            resolve(results.data);
                        });
                        break;

                    default: // dev - local json
                        $.getJSON('Content/data/Stores.json', function (json) {
                            resolve(json);
                        });
                }
            });
        };

So, now I've got one promise nested inside the other. It seems to work, I'm just not sure it's efficient.

Upvotes: 0

Gregori
Gregori

Reputation: 829

Without testing yet in plunker, your service is injected as 'MyService' not 'StoreService', so it should look like:

storeController.$inject = ['$scope', '$http', '$q', '$window', 'StoreService', 'toastr']; function storeController($scope, $http, $q, $window, StoreService, toastr) {

StoreService.getStores().then(

Upvotes: 1

seanhodges
seanhodges

Reputation: 17524

You need to return the promise resolver so that you can invoke the .then() function on it. For example:

this.getStores = function() {
  return $q(function(resolve, reject) {
    $.getJSON('Content/data/Stores.json', function (json) {
        resolve(json);
    });
  });
}

Or the older CommonJS notation:

this.getStores = function() {
  var deferred = $q.defer();
  $.getJSON('Content/data/Stores.json', function (json) {
      deferred.resolve(json);
  });
  return deferred.promise;
}

Remember to inject $q into your StoreService. See here for more info: https://docs.angularjs.org/api/ng/service/$q

Upvotes: 1

Related Questions