0

I have a directive which I want to use for file upload in my application.

But when a file is selected it doesn't update the model in the controller.

The directive is as following:

export interface IFileInputModel {
    fileName: string;
    fileContent: any;
}

export class FileInput implements ng.IDirective {
    constructor() {
    }
    restrict = "EA";
    replace = true;
    template = `<input type="file" class="form-control" accept="image/*"/>`;
    scope: {
        image: '='
    };

    link = (scope, element, attrs, ctrl) => {
        let updateModel = function () {
            let file = element[0].files[0];

            let reader = new FileReader();
            reader.readAsDataURL(file);

            reader.onload = function (evnt: any) {
                let model: IFileInputModel = {
                    fileName: file.name,
                    fileContent: evnt.target.result
                };

                scope.$apply(function () {
                    scope.image = model;
                });
            };
        };

        element.bind('change', updateModel);
    }

    static factory(): ng.IDirectiveFactory {
        const directive = () => new FileInput();
        return directive;
    }
}

and this how I'm using it in the HTML

<file-input ng-model="controller.img"></file-input>

This renders the valid directive template, but when I select a file and upload it the controller.img is not updated in the controller.

What am I doing wrong?

Note - this is an AngularJS 1.X application in Typescript.

EDIT

Based on the duplicate marked question, I changed my directive to

 export class FileInput implements ng.IDirective {
        constructor(private $parse) {
        }
        restrict = "EA";
        scope: {
            fileread: "="
        }

        link = (scope, element, attrs, ctrl) => {

            element.bind("change", function (changeEvent) {
                var reader = new FileReader();
                reader.onload = function (loadEvent) {
                    scope.$apply(function () {
                        scope.fileread = (loadEvent.target as any).result;
                    });
                }
                reader.readAsDataURL(changeEvent.target.files[0]);
            });

        }
}

and tried using it as:

<input type="file" fileread="controller.img" file-input/>

but the controller.img is never updated in the controller.

Dawood Awan
  • 7,051
  • 10
  • 56
  • 119

1 Answers1

0

AngularJS does not support file inputs, you will have to manually handle it by adding an onchange event listener to the input:`

element[0].addEventListener('change', event => {
   const files = event.target.files;
   // etc...
});
andriusain
  • 1,211
  • 10
  • 18