0

I'm in this problem a days. What happens is the following when I try to click the update image button I can not do the image update on the first try despite my console.log it return me the correct value. What happens is that when I make the request to the backend the first time I load the update button it always returns the blob of the image that was previously and when I try again it returns the blob of the image that I tried to perform in the previous moment and Inserts into DB. In short he is always with a late request and I do not do the least because. I already tried to add the $ scope. $ Apply () and it did not work.

First update the blob of the previous image

Second update the blob correct of the image

In short I need to do update twice to be able to change the image to the one I want.

Code:

function uploadFile(){
    var file = $scope.profilePic;
    var blob = new Blob([file], {
        "type": "text/html"
    });

    var reader = new FileReader();

    reader.onload = function(e) {
        $scope.text = e.target.result.split(',')[1];
        $scope.loadedUser.profilePic = $scope.text;
    }

    reader.readAsDataURL(blob);

}; 

Html:

<div layout-gt-sm="row" style="margin-bottom: 20px;">                                                    
    <input type="file" name="profilePic" fileread="profilePic"> 
</div>

APP:

app.directive("fileread", [function () {
    return {
        scope: {
            fileread: "="
        },
        link: function (scope, element, attributes) {
            element.bind("change", function (changeEvent) {
                scope.$apply(function () {
                    scope.fileread = changeEvent.target.files[0];
                    // or all selected files:
                    // scope.fileread = changeEvent.target.files;
                });
            }); 
        } 
    }
}]);

1 Answer 1

0

Part of the problem is that the directive uses two-way = binding with isolate scope. A digest cycle is necessary to transfer the data from the isolate scope to the parent scope.

One approach is to use expression & binding and expose the file as a local:

<div layout-gt-sm="row" style="margin-bottom: 20px;">
    <input type="file" name="profilePic" fileread="profilePic = $file">
</div>
app.directive("fileread", function () {
    return {
        scope: {
            //fileread: "="
            fileread: "&"
        },
        link: function (scope, element, attributes) {
            element.bind("change", function (changeEvent) {
                scope.$apply(function () {
                var file = changeEvent.target.files[0];
                scope.fileread({$file: file});
                scope.$apply()
            }); 
        } 
    }
});

In the above example, when a change event occurs, the directive evaluates the Angular expression defined by the fileread attribute with the file exposed as $file. The $file value is immediately available to the parent scope without the need of a watcher (and digest cycle) to transfer the value from isolate scope to parent scope.

Another problem is that reader.onload event occurs outside the AngularJS framework and needs a $scope.$apply() to process the changes to scope. For more information, see SO: FileReader onload only works the second time around in browsers.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.