Angularjs, Directive use a service which make a http request first

I want to implement a directive, which function is mainly display the banner image. The banner image url is got by making a get request to server. So I write a service to get the image url as below:

service('NavBannerService', ['urls', '$http', '$cookies', function(urls, $http, $cookies){
    var banner_pic_url = '';
    var refresh_banner = function(){
        $http.get(urls.api + '/news/banner_url').success(function(data){
            //console.log(data);
            banner_pic_url = data.banner;
        }); 
    };
    refresh_banner();
    return {
        nav_pic: function(){
            return banner_pic_url;
        }
    };
}])

and my directive is:

directive('navBanner', ['urls', 'NavBannerService', function(urls, nbs){
    return {
        restrict: 'E',
        scope: {

        },
        controller: function($scope){
            $scope.banner_pic_url = nbs.nav_pic();
        },
        templateUrl: urls.part + '/directive_html/nav_banner.html'
    };
}])

But sometimes the $scope.banner_pic_url in the directive controllers will be '', because the nbs.nav_pic() called before the http request get a response.

How can I solve this problem? Or is there any better solutions. ( Using service to get the banner_url is because the directive will be in many pages, I don't want to call the page_url each time getting in a new page)

Thank you.

Your first issue is that you're trying to assign the data.banner to banner_pic_url in $http.get() which is returns a promise. So banner_pic_url is always going to be an empty string.

What you need to do is resolve the promise, as show below. I've rewritten it somewhat.

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

app.service('NavBannerService', ['$http', '$q', function ($http, $q) {
    var deferred = $q.defer();
    var service = {};
    service.getImage = function () {
        $http.get('http://jsonplaceholder.typicode.com/photos/1').success(function (data) {
            deferred.resolve(data.url);
        }).error(function () {
            // deferred.reject('server error');
        });

        return deferred.promise;
    };

    return service;

}]).directive('navBanner', ['NavBannerService', function (nbs) {
    return {
        restrict: 'E',
        scope: true,
        replace: true,
        template: '<div><img ng-src={{banner_pic_url}}></div>',
        link: function ($scope) {
            nbs.getImage().then(function(imageUrl){
                $scope.banner_pic_url = imageUrl;
            });
        }
    };
}]);

FIDDLE