Edit in JSFiddle

//    A little bit of data needed to get jsfiddle to fake an ajax request
var fiddleResponse = 'json=' + encodeURIComponent(angular.toJson({
    name: "TaLy"
}));
var fiddleHeaders = {
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }
};

var app = angular.module('app', []);

app.factory('NameService', function ($http, $q) {

    //    Create a class that represents our name service.
    function NameService() {

        var self = this;

        //    Initially the name is unknown....
        self.name = null;

        //    getName returns a promise which when fulfilled returns the name.
        self.getName = function () {

            //    Create a deferred operation.
            var deferred = $q.defer();

            //    If we already have the name, we can resolve the promise.
            if (self.name !== null) {
                deferred.resolve(self.name + " (from Cache!)");
            } else {
                //    Get the name from the server.
                $http.post('/echo/json/', fiddleResponse, fiddleHeaders)
                    .success(function (response) {
                    self.name = response.name;
                    deferred.resolve(response.name + " (from Server!)");
                })
                    .error(function (response) {
                    deferred.reject(response);
                });
            }

            //    Now return the promise.
            return deferred.promise;
        };
    }

    return new NameService();
});

app.controller('MainController', function ($scope, NameService) {

    //    We have a name on the code, but it's initially empty...
    $scope.name = "";

    //    We have a function on the scope that can update the name.
    $scope.updateName = function () {
        NameService.getName()
            .then(
        /* success function */
        function (name) {
            $scope.name = name;
        },
        /* error function */
        function (result) {
            console.log("Failed to get the name, result is " + result);
        });
    };
});
<div ng-app="app">
    <div ng-controller="MainController">
        <p><strong>Name:</strong> {{name}}</p>
        <button ng-click="updateName()">Update Name</button>
    </div>
</div>