1

I am new to angularjs and want to add new feature in existing code. But code is not working as expected. I know i am not doing it the right way. Please correct me where is the mistake. I don't know why controller is not used but directive is used in this approach?

Here is my custom service and custom directive directive code.

Service code:

angular.module("quickquiz-builder").service("SettingsService", function ($http, $q) {
    return {
    /* Return deffered promise response */
        get: function() {
            var deferred = $q.defer();
            $http.get('get.php')
            .then(function(response){
                var config = response.data.config;
                config = JSON.parse(config);
                this.generalSettings = config.settings;
                deferred.resolve(this);
            })
            .catch(function(response){
              deferred.reject(response);
            });
            return deferred.promise;
        }
    }
})

Custom Directive:

angular.module("quickquiz-builder").directive("quizbuilderSettings", ["SettingsService", "QuestionsService", "$filter", function (SettingsService, QuestionsService, c) {
    return {
        restrict: "E",
        scope: {},
        templateUrl: "templates/settings.html",
        controllerAs: "ctrl",
        controller: ["$scope", function (scope) {
            SettingsService.get().then(function (data){
    /* get response from service inside callback */
                this.settingsService = data;
                scope.settingsService = this.settingsService;
                this.questionsService = QuestionsService;
                console.log(1);
                console.log(scope.settingsService.generalSettings);
                console.log(1+' end');
            }).catch(function(e){
                console.dir(e);
            });
        }]
    }
}])

The service response is retrieved successfully inside callback in directive. But this response is not binding with view.

A piece of template code is:

<div layout="row" class="option">
    <md-switch class="md-primary var-label" aria-label="graded" ng-model="ctrl.settingsService.generalSettings.graded" ng-change="ctrl.onChangeGraded()">
         <strong>Graded</strong>
    </md-switch>
    <p flex=""><span ng-if="ctrl.settingsService.generalSettings.graded">The quiz has at least one graded question (a question that has a right/wrong answer).</span><span ng-if="!ctrl.settingsService.generalSettings.graded">It's not a graded quiz.</span>
    </p>
</div>
3
  • The restrict: "E" means that it's expected to be an element, like < quizbuilderSettings></quizbuilderSettings>. Please include the code where the directive is included as well. It's also better to not alias $scope to scope for readability. Commented May 22, 2019 at 14:28
  • The element exists exactly where it should be. The issue seems with call-backs. The code written inside callback (get().then function) inside directive is not binding with view. If I don't use callback and return static values from service and use it in directive without callback (then), it works perfectly fine. I don't understand what is the issue with ng-model will callback... Commented May 22, 2019 at 17:41
  • 1
    It's probably related to your scoping but can't tell without more code. Commented May 22, 2019 at 17:53

1 Answer 1

1

@doublesharp, you are absolutely right. The problem was with data binding and scoping.

  1. First we need to bind the data properly inside App directive, so it is available in the view.

    scope.settingsService = this.settingsService;

Which I was doing already right. Because simply with 'this' operator, its scope was inside the promise callback function. 'this' operator was not representing for controller/directive level.

  1. Access the value properly in view.

Use

<element nm-model="settingsService.generalSettings.graded"></element>

Instead of

<element nm-model="ctrl.settingsService.generalSettings.graded"></element>

Accessing the variable/object inside view with ctrl (i.e controllerAs) was not according to scope of directive. Because binding at directive level was not with 'this' operator.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.