I am attempting to follow this [tutorial] but can't get it working.
My Angular controller is logging undefined
for a model created in my directive.
Here is a [JSFiddle] of it working created my author of tutorial.
The problem is the view can find $scope.myFile
and but controller does not ($scope.myFile
is undefined
).
The view displays {{ myFile.name }}
(as just example my-image.jpg
). The myFile
variable is a JS object containing data on selected file. This works fine. The directive seems to be assigning the model the value of selected file (and thus displays it correctly in view).
<input file-model="myFile" type="file"/ >
<div class="label label-info">
{{ myFile.name }}
</div>
<button ng-click="uploadDocs()">Click</button>
Here is the directive I got from this [tutorial].
Since input type file
can't use ng-model
, this directive sets up the model to be associated with an file
input, assigning to it every time the file fires change
event.
directive('fileModel', [
'$parse',
function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
if (element[0].files.length > 1) {
modelSetter(scope, element[0].files);
}
else {
modelSetter(scope, element[0].files[0]);
}
});
});
}
};
}
]).
In the controller I just log $scope.myFile
. This is called from the button in the HTML above.
Ideally, I'd be uploading the files to server here, but I can't because $scope.myFile
is undefined.
$scope.uploadDocs = function() {
var file = $scope.myFile;
console.log($scope.myFile);
};
Can someone tell me why the view would be recieving $scope.myFile
but the controller logs undefined
for $scope.myFile
?
I ran into the same problem when trying to access a directive's variable from the controller. In my case I could make myFile
available to the controller, but I had to assign it to scope.$parent.$parent.myFile
from within the directive. I didn't want to hard code in a depth of ancestry in order to access the variable, so I ended up using a service to share the variable between directive and controller:
.factory('fileService', function() {
var files = [];
return files;
})
My directive code changed to use the service instead of attrs.fileModel
that was used in the tutorial:
.directive('fileModel', ['$parse', 'fileService', function ($parse, fileService) {
return {
restrict: 'A',
link: function(scope, element) {
element.bind('change', function(){
scope.$apply(function(){
if (element[0].files != undefined) {
fileService.push(element[0].files[0]);
console.log('directive applying with file');
}
});
});
}
};
}])
Then, after injecting fileService into the controller I could access the file directly from fileService:
$scope.uploadDocs = function() {
console.log(fileService);
};
This issue is seen in couple of Angular versions, where file object can't be set the scope variable. As a work around make, pass the field to controller, use this file object to upload ( not from scope)
HTML Form
<form>
<div class="form-group">
<label for="myFileField">Select a file: </label>
<input type="file" file-model="myFile" /> <label>File Name:</label>
<input type="text" ng-model="filename"></input>
</div>
<button ng-click="uploadFile(myFile)" class="btn btn-primary">Upload File</button>
</form>
Controller
$scope.uploadFile = function (file1) {
var file = $scope.myFile; // this is undefined
console.log("My file =" +file1); // you get this
// Make http call to upload the file or make service call
}
Hope this solves the problem
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With