4

As I am new to AngularJS, I Don't know how to upload file in MVC using AngularJS. I am trying to upload some files without any specific type or extension, but failed.

I created a javascript file which have-

Here is serviceJS-

    var app = angular.module("app", []);        
    app.service('FileUploadService', ['$http', function ($http) {      
            this.uploadFileToUrl = function (file,  uploadUrl) {    
            var fd = new FormData();   
            fd.append('file', file);   
            $http.post(uploadUrl, fd, {   
                transformRequest: angular.identity,   
                headers: { 'Content-Type': undefined }   
            })   
            .success(function () {   
            })    
            .error(function () {    
            });     
        }   
    }]);

This is controller part-

    app.controller('FileUploadController', ['$scope', 'FileUploadService', function($scope, FileUploadService) { 
            $scope.uploadFile = function () {
            var file = $scope.myFile;
            console.log('file is ');
            console.dir(file);
            var uploadUrl = "/Home/FileUploadFromAngular";
            FileUploadService.uploadFileToUrl(file, uploadUrl);
        };
    }]);

And, In view page,

 <script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/AngScript/FileUpload.js"></script>
<script src="~/Scripts/angular-ui/ui-bootstrap.min.js"></script>
    <div ng-controller="FileUploadController">
        <input type="file" ng-model="myFile" />
        <button ng-click="uploadFile()">Upload</button>
    </div>

It is taking myFile as undefined in controller. I am unable to debug this.
Thanks in advance.

2

3 Answers 3

5

You cannot bind the <input type="file"> to a $scope variable. You will need to create a directive which captures the onchange event of the file input tag. For example <input type="file" name="myFile" file-upload/> and the directive looks like this:

angular.module("app.directives", []).directive('fileUpload', function () {
return {
    scope: true,
    link: function (scope, el, attrs) {
        el.bind('change', function (event) {
            var files = event.target.files;
            //iterate files since 'multiple' may be specified on the element
            if(files.length == 0){
                scope.$emit("fileSelected", { file: null, field: event.target.name });
            } else{
                for (var i = 0;i<files.length;i++) {
                    //emit event upward
                    scope.$emit("fileSelected", { file: files[i], field: event.target.name });
                }
            }
        });
    }
};
});

After that, you can catch the broadcast in your controller like this:

$scope.$on("fileSelected", function (event, args) {
    $scope.$apply(function () {
        switch (args.field) {
            case "myFile":
                $scope.myFile = args.file;
                break;
            default:
                break;
        }
    });
});

Your Service method can be comething like this:

this.uploadFileToUrl = function (file,  uploadUrl) { 
    return $http({
        method: 'POST',
        url: uploadUrl,
        headers: { 'Content-Type': undefined },
        transformRequest: function() {
            var formData = new FormData();
            if(file){
               formData.append("myFile", file); 
            }
            return formData;
        }
    })
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for quick response.. still m getting an error of injector . can you pls tell me how to call a scope variable in view on event onchange?
Ow ye, that is because oyu havent got an angular app.directives module. I edited my code.
thanks, that problem is resolved.. but now it is saying file is undefined with 500 internal server error :(
Then you have to debug your backend :) I dont know what is wrong there.
|
0

Try this. Controller

/**** FILE UPLOAD *****/

   $scope.upload = [];
    $scope.fileUploadObj = {
        "ID": $rootScope.filesReturn.id
    }

    $scope.onMultiFileSelect = function ($files) {
        //$files: an array of files selected, each file has name, size, and type.
    $scope.errArr = [];
    for (var i = 0; i < $files.length; i++) {
        var $file = $files[i];
        if ($file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || $file.type === 'application/vnd.ms-excel') {
            (function (index) {
                $scope.upload[index] = $upload.upload({
                    url: host + 'api/Return/ReturnUpload',
                    method: "POST",
                    data: { fileUploadObj: $scope.fileUploadObj },
                    file: $file
                }).progress(function (evt) {
                    // get upload percentage Can hook to some Load view thing
                    //console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
                }).success(function (data, status, headers, config) {
                    // file is uploaded successfully
                    $scope.chkErr();
                }).error(function (data, status, headers, config) {
                    // file failed to upload
                    $scope.setErr(data.returnDataErr);
                    $scope.chkErr();
                });
            })(i);
        }
        else
        {
            $scope.setErr($file.name + " is not an .xls .xlsx");
            $scope.chkErr();
            (i);
        }
    }//END FOR
    $scope.abortUpload = function (index) {
        $scope.upload[index].abort();
    }
}
//check if there is errormsg in array.
$scope.chkErr = function () {
    if ($scope.errArr.length > 0) {
        //IS ERROR
        $scope.errorUpload = true;
        $scope.$apply();
        //$scope.errorMessage = data.returnDataErr;
    }
    else {
        //IS SUCCESS
        $scope.noFiles = false;
        $scope.errorUpload = false;
        $scope.getFiles();
    }
}

View

                            <div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
                                <input style="float:left" type="file" ng-file-select="onMultiFileSelect($files)" multiple>
                                <div style ="float:left">
                                    <a ng-show="!noFiles" class=" btn btn-default btn-xs" ng-click="confirmClick() && deleteItem()" confirm-click data-localize="DELETE">
                                        Delete All
                                    </a>
                                </div>
                            </div>

API or MVC controller

  [Route("ReturnUpload")]
    [HttpPost]
    public async Task<HttpResponseMessage> ReturnUpload()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
        }

        try
        {
            var provider = GetMultipartProvider();
            var result = await Request.Content.ReadAsMultipartAsync(provider);

            //JSON data from upload ( returns id )
            var returns = GetFormData<UploadReturnBindingModel>(result) as UploadReturnBindingModel;

            //Get original FileName from result
            var originalFileName = GetDeserializedFileName(result.FileData.First());

            //Get data from UplaodedFile info.  paths created time etc.
            var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);

            var ret = db.ReturnRecords.Single(a => a.id == returns.ID);
            var tenantId = db.Users.Find(User.Identity.GetUserId()).Tenant.id;
            var entityId = ret.entityId;
            if (ret.status == ReturnStatus.Converting.ToString())
            {
                // If you want to send something to the .error callback, 
                var returnDataErr = "Convertion in Progress, try again later";
                return this.Request.CreateResponse(HttpStatusCode.BadRequest, new { returnDataErr });
            }

            var ToDir = uploadedFileInfo.DirectoryName + "\\" + tenantId + "\\" + entityId + "\\" + returns.ID + "\\Upload\\";
            if (!Directory.Exists(ToDir))
            {
                Directory.CreateDirectory(ToDir);
            }
            else if (System.IO.File.Exists(ToDir + originalFileName))
            {
                var toDelete = db.FileRecords.Single(a => a.path + a.name == ToDir + originalFileName && a.returnId == returns.ID);
                db.FileRecords.Remove(toDelete);
                System.IO.File.Delete(ToDir + originalFileName);
            }
            System.IO.File.Move(uploadedFileInfo.FullName, ToDir + originalFileName);

            var file = new Portal.Models.File();
            file.userName = db.Users.Find(User.Identity.GetUserId()).UserName;
            file.name = originalFileName;
            file.path = ToDir;
            file.returnId = returns.ID;
            file.timeStamp = DateTime.Now;
            //var createdTime = uploadedFileInfo.CreationTime;
            //var currentUser =  User.Identity.GetUserId();
            db.FileRecords.Add(file);


            // Update the ret status that files has been uploaded.
            ret.status = ReturnStatus.DocumentsUploaded.ToString();

            db.SaveChanges();


        }
        catch(Exception ex)
        {
            // If you want to send something to the .error callback, use the HttpStatusCode.BadRequest instead
            log.Error(ex);
            var returnDataErr = "Failed creating file";
            return this.Request.CreateResponse(HttpStatusCode.BadRequest, new { returnDataErr });
        }
        // Through the request response you can return an object to the Angular controller
        // You will be able to access this in the .success callback through its data attribute
        var returnDataOk = "OK";
        return this.Request.CreateResponse(HttpStatusCode.OK, new { returnDataOk });
    }

Comments

0
<input class="input-sm" type="file" ng-model="Registration_CTRL.IDProdf" onchange="angular.element(this).scope().FN_UPLOAD_FILE(event)" multiple />


$scope.FN_UPLOAD_FILE = function (evt) {
        var _file = new File([""], evt.target.file);
        var a = evt.target.files;
        var _formData = new FormData();
        _formData.append("IDPROOF", evt.target.files[0]);
        _formData.append("EMPID", $scope.Registration_CTRL.ID);
        $http({
            method: 'POST',
            url: '@Url.Action("Upload_Employee_IDProof", "Registration")',
            headers: { 'Content-Type': undefined },
            data: _formData
        }).then(function (data) {
            $scope.Registration_CTRL.IDProdf = data.data.aaData;
        });
    }

[HttpPost]
public JsonResult Upload_Employee_IDProof()
{
    string _fileName = "";
    try
    {
        if (Request.Files.Count > 0)
        {
            var _empid = int.Parse(Request.Form["EMPID"]);
            var _file = Request.Files[0];
            var _fName = Request.Files["IDPROOF"].FileName;
            var _dotIndex = _fName.LastIndexOf('.');
            var _ext = _fName.Substring(_dotIndex);
            var _configpath = RequestHelpers.RequestHelpers.GetConfigurationValue("IDProofPath");
            _fileName = _empid + "_IDPROOF" + _ext;
            var _dirPath = Server.MapPath(_configpath);
            var _filePath = Server.MapPath(_configpath) + _fileName;
            if (System.IO.Directory.Exists(_dirPath))
            {
                if (System.IO.File.Exists(_filePath))
                {
                    System.IO.File.Delete(_filePath);
                }
                _file.SaveAs(_filePath);
            }
            else
            {
                System.IO.Directory.CreateDirectory(_dirPath);
                _file.SaveAs(_filePath);
            }
        }
    }
    catch (Exception ex)
    {
        return Json(new { aaData = ex.Message }, JsonRequestBehavior.AllowGet);
    }
    return Json(new { aaData = _fileName }, JsonRequestBehavior.AllowGet);
}

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.