nosthertus nosthertus - 6 months ago 10
AngularJS Question

Angularjs: Create a new scope property inside a directive

The value is never shown on the DOM and i'm just trying to see if this way works..

What i am trying to do is create a new scope value inside the directive and show it to the DOM

app.directive("rest", ["restFactory", function($rest){
return {
restrict: "A",
scope: {
uri: "@rest",
},
link: function(scope){
scope.$rest = [];

$rest.batch(scope.uri)
.then(function(data){
scope.$rest = data;
});
}
}
}]);


the data i am trying to show comes from a function that returns a promise, and with the promise comes the data i want to use in the DOM

the HTML is coded like this:

<div rest="accounts">
<div ng-repeat="data in $rest">
{{data.id}}
</div>
</div>


this is the first directive i ever did.

Answer

I made this plunker to explain why your directive don't work.

<div rest="accounts">
    <!-- You can't access the directive variable $rest from here 
         The directives variables are only available on it's template. -->
    <div ng-repeat="data in $rest">
        {{data.id}}
    </div>
</div>


This will work:

app.directive("restTwo", function() {
    return {
        restrict: "A",
        scope: {},
        // It will work. I put the template in here.
        // You can only access the directive variables from it's template
        template: '<div ng-repeat="data in $rest">{{data.id}}</div>',

        link: function(scope, el, attr) {
            console.log(attr.rest); // output = accounts

            //data
            scope.$rest = [{
                'id': 1,
                'name': 'John Doe'
            }, {
                'id': 2,
                'name': 'Johana Doe'
            }];
            console.log(scope.$rest);
        }
    }
});


I suggest you to make a factory and make your api call's in it like this:

app.factory('myFactory', function($http) {

    // GET example
    this.get = function(string) {
        return $http({
            method: 'GET',
            url: 'https://api.github.com/search/repositories?q=' + string
        });
    }

    // Your request here
    this.yourRequest = function(uri) {
        // return $rest.batch(uri);
    }

    return this;
});

And in your controller:

app.controller('MainCtrl', function($scope, myFactory) {
    $scope.myData = [];


    myFactory.get('tetris').then(function successCallback(response) {
        // this callback will be called asynchronously
        // when the response is available
        $scope.myData = response.data.items;
    }, function errorCallback(response) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
    });

});

View:

<div ng-repeat="data in myData">
    {{data.id}}
</div>


If you REALLY want to use a directive for this (I do not recommend):
Directive:

app.directive("restThree", function() {
    return {
        restrict: "A",
        scope: {
            'data': '='
        },
        link: function(scope, el, attr) {
            //console.log(attr.rest); // output = accounts

            //data
            scope.$rest = [{
                'id': 1,
                'name': 'John Doe'
            }, {
                'id': 2,
                'name': 'Johana Doe'
            }];

            scope.data = scope.$rest;
        }
    }
});

View:

<div rest-three="accounts" data="directiveData">
    <div ng-repeat="data in directiveData">
        {{data.id}}
    </div>
</div>