0

This is my directive file code

function imageUploadDirective(fileReader, rootScope) {

function imageUploadLinker(scope, elem, attr) {

    scope.$inputFileElement = elem.find(":file");

    scope.$inputFileElement.bind("change", function (e) {

        rootScope.invalid_image_msg = "";

        e.stopPropagation();
        var files = e.target.files === undefined ? (e.target && e.target.value ? [{
                name: e.target.value.replace(/^.+\\/, '')
            }] : []) : e.target.files;
        console.log("files: ", files);
        console.log("FILE ZERO INDEX");
        console.log(files[0]);

        if (files.length === 0 || files.length > 1 || !fileReader.isImageFile(files[0])) {

            if (!fileReader.isImageFile(files[0])) {
                rootScope.invalid_image_msg = "IT's Not an Image, Please Select Valid Format of Image";
            } else {
                rootScope.invalid_image_msg = "Please Select an Valid Image";
            }
            rootScope.is_image_valid = false;
            console.log("reset");
            scope.reset();
            return;
        }

        scope.fileName = files[0];
        fileReader
                .readAsDataUrl(scope.fileName, scope)
                .then(function (result) {

                    rootScope.userInfo.imageSrc = result;
                });
    });
}

return {
    restrict: "EA",
    templateUrl: "/user/imageUploadTemplate",
    scope: {
        name: "@",
        alt: "@",
        selectBtnTitle: "@",
        changeBtnTitle: "@",
        removeBtnTitle: "@",
        noImage: "@"
    },
    controller: "lugbeeUserSPACtrl",
    link: imageUploadLinker
};
}

imageUploadDirective.$inject = ["fileReader", "$rootScope"];

angular
    .module("lugbeeUserSPA")
    .directive("imageUpload", imageUploadDirective);

This is my template html file code

<div class="fileinput">

<div data-text="{{noImage}}" class="thumbnail image-upload-preview">
    <img ng-show="hostInfo.imageSrc" ng-src="{{hostInfo.profile_image_path}}" alt="{{imageSrc ? alt : ''}}">
</div>
<div>
    <span class="btn btn-default btn-file">
        <span ng-if="!fileName" ng-click="openFileSelector()">{{:: selectBtnTitle}}</span>
        <span ng-if="!!fileName" ng-click="openFileSelector()">{{:: changeBtnTitle}}</span>
        <input type="file" class="inputfile" name="{{:: name}}" id="{{:: name}}">
    </span>
    <a href="#" class="btn btn-default" ng-click="reset()" ng-if="!!fileName">{{:: removeBtnTitle}}</a>
</div>

How to remove controller option from the above code and also how can I replace scope option object with controller scope variable. please help me to solve this problem because the controller onload function calls two times because of controller option that's why I want this.

Chetna Joshi
  • 141
  • 1
  • 10
  • Please post your html, my guess is that you might be using in your template ng-controller="lugbeeUserSPACtrl", which is not needed since the controller is already defined in your directive. But cannot tell for sure without the html. Or if you could recreate the issue in a Plunker or JSFiddle that would be better. – Urielzen Mar 11 '19 at 07:17
  • @Urielzen i am updating my question by adding html but one thing i want to clear you that im not using ng-controller in my template html – Chetna Joshi Mar 11 '19 at 10:04

2 Answers2

0

I have recreated a scenario with your code, and the controller is only activated once. The issue must be somewhere else.

function imageUploadDirective(fileReader, rootScope, $timeout) {

  function imageUploadLinker(scope, elem, attr, ngController) {

    ngController.onLoad("I have access to this method now also from the link function");

    scope.$inputFileElement = elem.find(":file");

    scope.$inputFileElement.bind("change", function(e) {
    
      rootScope.invalid_image_msg = "";

      e.stopPropagation();
      var files = e.target.files === undefined ? (e.target && e.target.value ? [{
        name: e.target.value.replace(/^.+\\/, '')
      }] : []) : e.target.files;
      console.log("files: ", files);
      console.log("FILE ZERO INDEX");
      console.log(files[0]);

      if (files.length === 0 || files.length > 1 || !fileReader.isImageFile(files[0])) {

        if (!fileReader.isImageFile(files[0])) {
          rootScope.invalid_image_msg = "IT's Not an Image, Please Select Valid Format of Image";
        } else {
          rootScope.invalid_image_msg = "Please Select an Valid Image";
        }
        rootScope.is_image_valid = false;
        console.log("reset");
        scope.reset();
        return;
      }

      scope.fileName = files[0];
      fileReader
        .readAsDataUrl(scope.fileName, scope)
        .then(function(result) {

          rootScope.userInfo.imageSrc = result;
        });
    });
  }

  return {
    restrict: "EA",
    templateUrl: "/user/imageUploadTemplate",
    scope: {
      name: "@",
      alt: "@",
      selectBtnTitle: "@",
      changeBtnTitle: "@",
      removeBtnTitle: "@",
      noImage: "@"
    },
    require: '^ngController',
    link: imageUploadLinker
  };
}

imageUploadDirective.$inject = ["fileReader", "$rootScope", "$timeout"];

angular
  .module('app', [])
  .directive('imageUpload', imageUploadDirective)
  .factory('fileReader', function() {
    return {};
  })
  .controller('lugbeeUserSPACtrl', function($scope) {
  
    this.onLoad = function onLoad(message) {
      console.log(message);
    };

    this.onLoad('controller activated when initialized in ngController');
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>

<body ng-app="app" ng-controller="lugbeeUserSPACtrl">

  <image-upload></image-upload>

  <script type="text/ng-template" id="/user/imageUploadTemplate">
    <div class="fileinput">
      <div data-text="{{noImage}}" class="thumbnail image-upload-preview">
        <img ng-show="hostInfo.imageSrc" ng-src="{{hostInfo.profile_image_path}}" alt="{{imageSrc ? alt : ''}}">
      </div>
      <div>
        <span class="btn btn-default btn-file">
        <span ng-if="!fileName" ng-click="openFileSelector()">{{:: selectBtnTitle}}</span>
        <span ng-if="!!fileName" ng-click="openFileSelector()">{{:: changeBtnTitle}}</span>
        <input type="file" class="inputfile" name="{{:: name}}" id="{{:: name}}">
        </span>
        <a href="#" class="btn btn-default" ng-click="reset()" ng-if="!!fileName">{{:: removeBtnTitle}}</a>
      </div>
  </script>
</body>
Urielzen
  • 476
  • 7
  • 17
  • so this is running twice – Chetna Joshi Mar 12 '19 at 07:02
  • Well, you have answered your own question. You really shouldn't be using a controller defined specifically for a directive in your index.html. If you need a controller in your body, give it a different name and separate the logic that belongs in the directive's controller and the logic that belongs in the outer (main) controller. – Urielzen Mar 12 '19 at 07:45
  • my problem is that i want to use the same controller for both not want to create separate controller so if you can help me that how can i create this directive without controller option then it would be great and i will thankful to you – Chetna Joshi Mar 12 '19 at 08:15
  • Please see updated answer, you would need to remove the controller property from your directive object and add the 'require' property to access the the parent ngController. You will have access to its methods in the link function. However I wouldn't recommend this approach, if there is functionality that the parent and children controller share, it would be better to create a service for that purpose, and use the service accordingly from within each controller as needed. – Urielzen Mar 12 '19 at 19:58
0

I found my solution if you remove scope option from directive and access controller scope variable in directive template than can solve this problem like this. Here is my updated code which can be used to solve this type of problem

function imageUploadDirective(fileReader, rootScope) {

function imageUploadLinker(scope, elem, attr) {

    scope.$inputFileElement = elem.find(":file");

    scope.$inputFileElement.bind("change", function (e) {

        rootScope.invalid_image_msg = "";

        e.stopPropagation();
        var files = e.target.files === undefined ? (e.target && e.target.value ? [{
                name: e.target.value.replace(/^.+\\/, '')
            }] : []) : e.target.files;
        console.log("files: ", files);
        console.log("FILE ZERO INDEX");
        console.log(files[0]);

        if (files.length === 0 || files.length > 1 || !fileReader.isImageFile(files[0])) {

            if (!fileReader.isImageFile(files[0])) {
                rootScope.invalid_image_msg = "IT's Not an Image, Please Select Valid Format of Image";
            } else {
                rootScope.invalid_image_msg = "Please Select an Valid Image";
            }
            rootScope.is_image_valid = false;
            console.log("reset");
            scope.reset();
            return;
        }

        scope.fileName = files[0];
        fileReader
                .readAsDataUrl(scope.fileName, scope)
                .then(function (result) {



                    console.log("VALUE OF USER INFO IN IMAGE DIRECTIVE");
                    console.log(rootScope.userInfo);

                    rootScope.userInfo.imageSrc = result;
                    rootScope.userInfo.profile_image_path = result;
                    rootScope.avatarFile = files[0];
                    rootScope.is_image_valid = true;



                    console.log("IN DIRECTIVE CODE IMAGE SRC");
                    console.log(rootScope.imageSrc);
                });
    });
  }

return {
    restrict: "EA",
    templateUrl: "/user/imageUploadTemplate",
    link: imageUploadLinker
};
}

imageUploadDirective.$inject = ["fileReader", "$rootScope"];

angular
    .module("lugbeeUserSPA")
    .directive("imageUpload", imageUploadDirective);
Chetna Joshi
  • 141
  • 1
  • 10