Sunday, November 16, 2014

Learning Angular | Using a factory to make an API call

I was recently building an Angular app in which I had a search page and a search results page. Obviously, the API call would be made after a user hit the search button on the search page, but the question was whether I should make the call from the search page or the search results page.

Search page on the left, search results on the right
My initial solution was extremely complex - I tried recording the selected parameters, and then I created a super-complicated route that allowed me to pass them into the the search results page. However, that was way too complicated, and I quickly realized that there had to be a better way.

After asking around a bit on some Angular help channels, I figured out that Angular services and factories are singletons! This means that I can make the call in the search controller, store the results in my API factory, and then bootstrap my search results controller user the cached results. This ended up being a much faster, simpler, neater implementation!

Here's how my final implementation worked:

Search function - searchController.js

$scope.search = function() {
        var searchParameters = {
            // create search object
        }
        
        API.search(searchParameters).success(function (data, status, headers, config) {
            $location.url('/results');
        });
    };


Controller - searchResultsController.js

// gets the cached results from the API
var data = API.getSearchResults();

    

API factory - API.js

angular.module("donorsApp").factory("API", ["$http", function ($http) {
    
    var constructSearchUrl = function (searchParameters) {
        //returns URL;
    }
    
    // cached results
    var results = null;
    
    return {

        // gets called from the searchController             
        search : function (searchParameters) {
            var request = $http.jsonp(constructSearchUrl(searchParameters));
            
            request.success(function (data, status, headers, config) {
                // caches the returned results
                results = data;
            });
            
            return request;
        },
        
        // gets called from the searchResultsController
        getSearchResults: function() {
            return results;
        }
        
    }
    

}]);

Lesson learned: don't make API calls from the controller, make them from a factory or a service, and then cache the results as needed. 

0 comments:

Post a Comment