Angularjs : accessing service methods from directive's link function

24,098

Instead of declaring the service in the link function, declare it when you are defining the directive:

So here:

AppDirectives.directive('feed',['FeedService',function(feedService) {

Then the feedService will be available to call inside the link function. The link function parameters are specifically defined as scope, element, attrs, ctrl so there is no straight dependency injection happening there (AFAIK).

Share:
24,098
Shahzeb Khan
Author by

Shahzeb Khan

code nerd

Updated on December 24, 2020

Comments

  • Shahzeb Khan
    Shahzeb Khan over 3 years

    i have a directive, and in its link function i want to access methods from a service. My code for directive is

    AppDirectives.directive('feed',['FeedService',function() {
    return {
        restrict : 'AE',
        scope : {
            feedLike: '&',
            feedItem : '=',
            feedDislike :'&',
            feedsArray :'=',
        },
        templateUrl :'resources/views/templates/feedTemplate.html',
    
        link : function(scope,element,feedService){
            console.debug("linking now");
            scope.likeComment = function(commentUid){
                console.debug("comment liked :"+commentUid);
            };
    
            scope.addComment = function(referenceFeedUid){
                console.debug("commentText : "+scope.commentText);
                var comment = {
                        user : "guest",
                        feedText : scope.commentText
                    };
                feedService.addComment(comment,referenceFeedUid).then(function(response){
                    console.debug("response ; "+response);
                //  $scope.feeds.unshift(response);
                });
            };
    
        },
        replace : true,
    
    };
    }]);
    

    and my service code is

    .factory('FeedService',function($http){
    
    return {
        postFeed : function (feed){
            /*$http.post('/feed/add',feed).success(function(response){
                console.debug("added "+response);
            }).error(function(){
                console.debug("error adding feed");
            });*/
    
            return $http.post('/feed/add',feed).then(function(response){
                return response.data;
            });
    
        },
    
        getFeeds : function(){
             return $http.get('/feed/get');
        },
    
        likeFeed : function(feedUid){
            return $http.get('/feed/'.concat(feedUid).concat('/like')).then(function(response){
                return response.data;
            });
        },
    
        dislikeFeed : function(feedUid){
            return $http.get('/feed/'.concat(feedUid).concat('/dislike')).then(function(response){
                return response.data;
            });
        }, 
    
        addComment : function (comment,referenceUid){
            var targetUrl = '/feed/'.concat(referenceUid).concat('/comment');
    
            return $http.post(targetUrl,comment).then(function(response){
                return response.data;
            });
    
        },
    
    };
    });
    

    when i call the add comment from directive's link, i am getting following error on firebug console.

    TypeError: Object #<Object> has no method 'addComment'
    at Object.scope.addComment (http://localhost:8080/feed/resources/js/directives.js:53:21)
    at http://localhost:8080/feed/resources/js/lib/angular/angular.js:6193:19
    at http://localhost:8080/feed/resources/js/lib/angular/angular.js:12684:13
    at Object.Scope.$eval (http://localhost:8080/feed/resources/js/lib/angular/angular.js:7840:28)
    at Object.Scope.$apply (http://localhost:8080/feed/resources/js/lib/angular/angular.js:7920:23)
    at HTMLButtonElement.<anonymous> (http://localhost:8080/feed/resources/js/lib/angular/angular.js:12683:17)
    at http://localhost:8080/feed/resources/js/lib/angular/angular.js:1926:10
    at Array.forEach (native)
    at forEach (http://localhost:8080/feed/resources/js/lib/angular/angular.js:110:11)
    at HTMLButtonElement.eventHandler (http://localhost:8080/feed/resources/js/lib/angular/angular.js:1925:5) 
    

    here is my directive template

     <ul class="media-list">
     <li class="media">
        <a class="pull-left" href="#"><img class="media-object" src="resources/images/holder.png" style="height:64px; width:64px;" alt="img"></a>
        <div class="media-body">
               <span><h4 class="media-heading">{{feedItem.userUid}}</h4>{{ feedItem.time | date:medium }}</span>
              <h5>{{feedItem.feedText}}</h5><h3></h3>
            <p> <a ng-click="feedLike(feedItem.feedLike)">Like </a> {{feedItem.like}} 
                <a ng-click="feedDislike(feedItem.feeddisLike)">Dislike</a>                                   {{feedItem.dislike}} 
            </p>
    
             <div ng-repeat = "comment in (feedsArray | filter:{referenceGroupId:feedItem.uid})">
                <div class="media">
                    <a class="pull-left" href="#"><img class="media-object" src="resources/images/holder.png" style="height:64px; width:64px;" alt="img"></a>
                    <div class="media-body">
                        <span><h4 class="media-heading">{{comment.userUid}}</h4>{{ comment.time | date:medium }}</span>
                        <h5>{{comment.feedText}}</h5><h3></h3>
                        <p> <a ng-click="likeComment(comment.uid)">Like </a> {{comment.like}} 
                            <a ng-click="commentDislike(comment.uid)">Dislike</a>{{comment.dislike}} 
                        </p>
                    </div>
                </div><br/>
            </div>
    
            <div>
                <input type="text" id="commentBox" ng-model="commentText"/>
                <button class="btn  btn-success" ng-click="addComment(feedUid)">Comment</button>
            </div> 
        </div>
    </li>
    
    </ul>
    

    what i am trying to do is that i want to access the addCommennt method from service. how can i fix it or is there any way that i can acess the service methods from inside the directive link function.

    Thanks in advance. regards,

  • Shahzeb Khan
    Shahzeb Khan over 10 years
    thank you so much for quick response. Its working fine now. Thanks again.
  • Abdulraheem Abid
    Abdulraheem Abid over 4 years
    Hi @ShahzebKhan. Your solution works perfectly. But I have a slightly different style of adding the link function like below: function mylink(scope, element, attrs){ myservice.mymethod() // can't access myservice here} function mydirective(myservice) { return { link: mylink, }; } How can i get access to the injected service in the link function if it is defined as above?
  • Shahzeb Khan
    Shahzeb Khan over 4 years
    @AbdulraheemAbid Bro, it has been almost 6 years I haven't worked on angular. Would be better if you ask a new question and add this as reference.