Inside my own Angular service, how do you get the return value back to the Controller that called the service?

user798719

I'm having trouble figuring out the success and error callbacks inside $http in angular and the "then" part of a promise. The $http service returns a promise. Is the "success" callback an example of a "then"? What if I stick $http inside my own service? How would I do this?

I think code is easier to show my questions:

app.controller('MainCtrl', function ($scope, $log, BooksService) {
    BooksService.retrieveAllBooks().then(function(results) {
      $scope.allBooks = results;
    });
  });


app.factory('BooksService', function($http,$log) {
  var service = {
    retrieveAllBooks: function() {
      return $http({
        method: 'GET','https://hugebookstore.org/allbooks'
        headers: {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }
      }).success(function(data, status, headers, config) {
         var allbooks = transformDataIntoBooksArray(data);//this function exists and just takes raw data and turns them into Book objects
         return allbooks;/*how is this "success" callback related to the "then"() callback in app.controller above?*/
      };
      }).error(function(data, status, headers, config) {
        $log.error('here is an error'+data + status + headers + config);
      });
    }
  };
  return service;
});

Questions about the app.controller code:

do I need to use a "then()" function inside app.controller?

I just want my controller to fetch me a list of all the books using the BooksService. The BooksService already has a "then" type of clause, which is the "success" callback. It seems like I have an unnecssary "then". Is that true?

Also, when is the "then" called, and can I put anything in the then's callback function's parameters?

I don't understand what parameters are supplied by default and what I can add.

Questions about the app.factory code:

First, this is what I understand the code to be doing.

I'm creating a BooksService using the factory() methods and not the service() methods available in Angular. I'm defining a function called retrieveAllBooks() that under the hood, is making an asynchronous GET request using $http in Angular, which itself is a service. RetrieveAllBooks() is a nothing more than a wrapper around the $http GET service, which makes it easy for clients to simply call BooksService.retrieveAllBooks() and be handed an array of Book objects.

When is the "success" callback executed and what is its relation to the "then" callback in my app.controller?

It doesn't appear that a return value inside my success() callback is ever returned back to app.controller. Why?

How can I get the allbooks array returned back to the app.controller which is what originally called BooksService.retrieveAllBooks()?

Are there any other parameters allowed in the success callback?

What do I need to return from the retrieveAllBooks() function definition? Do I return the $http promise alone, or do I need to return something from both the success and error callbacks as well?

I know this is longwinded but I hope that someone can help me, b/c this to pattern--separating out my network calls into its own service layer as opposed to calling $http directly inside my controller layer, will be done over and over again.

Thanks!!

Der Hochstapler

The success and error handlers are specific to the promise returned by $http. However, they're similar to .then(function onFulfill(){}, function onReject(){}).

It's up to you if you want to return that promise directly or implement something else.

Generally, your controller shouldn't be concerned about how your service handled the request. Thus, in my opinion, you shouldn't return that promise directly. Just handle the success and error case in your service. Return the result if the request succeeds and throw an Error if the request fails.

You can then use the generic .then(function onFulfill(){}, function onReject(){}) pattern in your controller, as this is always valid and expected with promises in Angular.

The onFulfill callback always receives your result as a parameter, the onReject callback receives the Error as a parameter.

So, what options do you have? Either drop your .success and .error callbacks in your service altogether and handle the transformation in the success case in your controller, or create a new deferred promise to return the transformed results:

app.factory('BooksService', function($http,$log,$q) {
  var service = {
    retrieveAllBooks: function() {
      var deferred = $q.defer();
      $http({
        method: 'GET','https://hugebookstore.org/allbooks'
        headers: {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }
      }).success(function(data, status, headers, config) {
         var allbooks = transformDataIntoBooksArray(data);//this function exists and just takes raw data and turns them into Book objects
         deferred.resolve( allbooks );
      };
      }).error(function(data, status, headers, config) {
        $log.error('here is an error'+data + status + headers + config);
        deferred.reject( new Error( 'here is an error'+data + status + headers + config );
      });
      return deferred.promise;
    }
  };
  return service;
});

Although, we can save that if we consider: - Errors are tracked by Angular already - The deferred is excess, and can be avoided - Content-Type and Accept are generated by Angular and the serer anyway. - We can save the anonymous wrapper for our action

So, we end up with:

app.factory('BooksService', function($http) {
  return {
    retrieveAllBooks: function() { 
      return $http.get('https://hugebookstore.org/allbooks').
             then(transformDataIntoBooksArray); // Error tracked by Angular already
      }
    }
});

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How do I return a promise from my service to my controller?

angular - How to get the value of a variable declared inside a component, to a service file?

Angular Filter Service inside Controller

How do I get a string value from service in an Angular component?

How to inject my service into my controller angular js

How do you test service or controller methods in grails 2.3

GET Service call is not getting called from Controller

How can Angular Service Function return response to controller

How do i mock a service that is inside a controller, and deals with promises?

Get current value of Subject.asObservable() inside Angular service

Angular 2 - how do I mock a service being called in a component?

Angular service written in typescript is undefined inside controller

Service not getting called in Controller

Service method not called in controller

service does not return data to controller in angular

Return a value from AngularJS API service to controller

Angular JS - My controller function its never return after execute my service script

How to make controller wait for service to return a value and how to access the returned value in controller?

How do you get a new service bean implementation instance each time you call an OSGi Blueprint service?

How do you properly configure a provider service in Angular.js

Angular 12 - how do you pass an object into your service

How do I get the value of an Observable in a service from a component and pass it to my view?

How can I add services inside my own service forwarding the IOptions?

How do I get my function inside a map to return a value instead of a Promise pending?

rxjs how to return an obsevable and a value togethere in angular service

What does this return statement do inside a service

How do I return the results of multiple asynchronous calls in Angular service

How do I get a value from a service in angular and insert it into an exported class?

Angular package using its own service inside component