0

I've recently started to upgrade from Bootstrap 3 to Bootstrap 4, and that requires I also upgrade from AngularJS 1.5.8 to a minimum of AngularJS 1.6.1. I have a simple AngularJS/MVC application with the following code setup:

/scripts/app.js (contains routing) /scripts/controllers.js (contains controllers, method calls, etc) /scripts/services.js (contains the callback methods that hit the C# controllers and bring back data, or "do things" (CRUD methods)

In my controllers.js, I have a method:

function init() {
    api.initialIndexLoad(
        function(result) {
            if (result.error) {
                notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(result.error));
            } else {
                vm.dataList = result.theDataFromCSharp;
            }
            vm.loaded = true;
        }
    );
}

init();

This makes a call to my services.js, where I have this code:

"use strict";

angular
.module("CustList.services", ["ngResource"])
.service("api",
    function api($resource, $http, notificationService) {
        function handleError(err, fn) {
            if (!fn) {
                notificationService.error(err);
            } else {
                fn(err);
            }
        }

        return {
            initialIndexLoad: function(callback, error) {
                $http.get("/Customers/InitialIndexLoad")
                    .success(callback)
                    .error(function(e) {
                        handleError(e, error);
                    });
            }
        };
    }
);

So, of course, after updating my libraries to AngularJS 1.6.1 (Actually, I went straight to AngularJS 1.7.5), I started to get errors, and after a while figured out that the promise syntax had changed. So I tried to change with it, and updated my services.js to be:

"use strict";

angular
.module("CustList.services", ["ngResource"])
.service("api",
    function api($resource, $http, notificationService) {
        function handleSuccess(response) {
            return response.data;
        }

        function handleError(err, fn) {
            if (!fn) {
                notificationService.error(err);
            } else {
                fn(err);
            }
        }

        return {
            initialIndexLoad: function() {
                $http
                    .get("/Customers/InitialIndexLoad")
                    .then(handleSuccess)
                    .catch(handleError);
            }
        };
    }
);

The errors went away, and I thought I had this upgrade licked, until I realized: I wasn't actually getting the data back! That new handleSuccess method I'd created was getting the data in the response, but the return response.data wasn't returning the data back to my controllers.js method, so I could plug it into vm.dataList.

It doesn't throw an error - it just does nothing. I'd appreciate help figuring this out!

benshabatnoam
  • 7,161
  • 1
  • 31
  • 52
PKD
  • 685
  • 1
  • 13
  • 37

2 Answers2

2

The service method needs to return the $http promise.

app.service("api",
    function api($http, notificationService) {
        function handleSuccess(response) {
            return response.data;
        }

        function handleError(err) {
            notificationService.error(err);
            throw err;
        }

        return {
            initialIndexLoad: function() {
                ̶$̶h̶t̶t̶p̶
                return $http
                    .get("/Customers/InitialIndexLoad")
                    .then(handleSuccess)
                    .catch(handleError);
            }
        };
    }
);

Notice that the errorHandler needs to re-throw the error. Otherwise the handler will convert the rejected promise to a fulfilled promise.

The controller needs to use the .then and .catch methods:

function init() {
    var promise = api.initialIndexLoad();
    promise.then(function(result) {
       if (result.error) {
            notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(result.error));
        } else {
            vm.dataList = result.theDataFromCSharp;
        }
        vm.loaded = true;
    }).catch(functions(err) {
        console.log(err);
        throw err;
    });
}

The .then method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback (unless that value is a promise, in which case it is resolved with the value which is resolved in that promise using promise chaining.

For more information, see

georgeawg
  • 48,608
  • 13
  • 72
  • 95
0

Return inside of initialIndexLoad

so

return $http
                    .get("/Customers/InitialIndexLoad")
                    .then(handleSuccess)
                    .catch(handleError);

Would guess this is it, maybe lost during refactor/upgrade.

shaunhusain
  • 19,630
  • 4
  • 38
  • 51