12

I have reviewed the questions and answers on this topic and I dont think they fully answer my issues which are:

  • the upload using the angular frontend (whichever way this is handled) sends the file data to a script on the server such as a php script (which is my preferred method). Once the php script has run I want to return to the page from which the upload was made and give a message there..I dont want the php page to display. Will appreciate some guidance on how to achieve this. Ideally what code to add to the php script.

  • I want to capture and save to a database info relating to the file such as its name and data entered/selected by the user such as a document category. Is there a way to achieve this as part of the file upload? ie ideally the user will complete entries in a form which includes a file upload button so that the user selects the file to upload but only on the form submit being clicked is the file upload actioned along with the other form data being returned for processing.

I have spent 3 days on this.. so any help will be great.

3
  • Have you tried something like ng-flow? It includes example angular and php code.
    – Tristan
    Nov 5, 2015 at 0:28
  • thanks for this. It looks great, but (a) I cannot get it to work (goes through the motions with no apparent errors but file is not actually uploaded..using their basic example..the transfer list shows file transfer completed as true (but file actually not uploaded) and uploading as false) and (b) I need to work out how to submit other data fields at the same time or as part of a clear work flow eg after uploading the file, the file name cld be entered by the file upload into a form field with the user left to enter the other form fields & then post to the REST for database entry. Nov 5, 2015 at 10:57
  • The answer provided by Midhun is comprehensive and is a good option. If you want to go with ng-flow I can give you details of how to include form data in the post?
    – Tristan
    Nov 5, 2015 at 20:17

1 Answer 1

27

You can use FormData objects to send form data to your server.It will allow you to send both files and text data at the same time. You can find more information about it here.

index.html

<body ng-controller="myCtrl">
    <div class="file-upload">
        <input type="text" ng-model="name">
        <input type="file" file-model="myFile"/>
        <button ng-click="uploadFile()">upload me</button>
    </div>
</body>


In app.js, we create a custom directive fileModel, in which we listen for changes to the content of the input element and change the value of the variable in the scope accordingly. This is achieved using the $parse service to set the value in our scope.

app.js

var myApp = angular.module('myApp', []);

myApp.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(){
                modelSetter(scope, element[0].files[0]);
            });
        });
    }
   };
}]);

// We can write our own fileUpload service to reuse it in the controller
myApp.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file, uploadUrl, name){
         var fd = new FormData();
         fd.append('file', file);
         fd.append('name', name);
         $http.post(uploadUrl, fd, {
             transformRequest: angular.identity,
             headers: {'Content-Type': undefined,'Process-Data': false}
         })
         .success(function(){
            console.log("Success");
         })
         .error(function(){
            console.log("Success");
         });
     }
 }]);

 myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){

   $scope.uploadFile = function(){
        var file = $scope.myFile;
        console.log('file is ' );
        console.dir(file);

        var uploadUrl = "save_form.php";
        var text = $scope.name;
        fileUpload.uploadFileToUrl(file, uploadUrl, text);
   };

}]);

save_form.php

 <?php

     $target_dir = "./upload/";
     $name = $_POST['name'];
     print_r($_FILES);
     $target_file = $target_dir . basename($_FILES["file"]["name"]);

     move_uploaded_file($_FILES["file"]["tmp_name"], $target_file);

     //write code for saving to database 
     include_once "config.php";

     // Create connection
     $conn = new mysqli($servername, $username, $password, $dbname);
     // Check connection
     if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
     }

     $sql = "INSERT INTO MyData (name,filename) VALUES ('".$name."','".basename($_FILES["file"]["name"])."')";

     if ($conn->query($sql) === TRUE) {
         echo json_encode($_FILES["file"]); // new file uploaded
     } else {
        echo "Error: " . $sql . "<br>" . $conn->error;
     }

     $conn->close();

?>


6
  • Many thanks Midhum. Will go through this tomorrow. Was in hospital today!! Nov 5, 2015 at 23:07
  • However, i use ng-file-upload, and I have tried Midhum's and examples from the github page, I get the following error: Not a valid marker at offset 623, found: 250 This appears to occur before the Upload function is called ..I have a console.log immediately wtihin the Upload function which is not called Any idea? Nov 6, 2015 at 14:14
  • I have edited the answer. This method is better and doesn't require external libraries. Do try it. Nov 7, 2015 at 8:23
  • Thanks Midhun. I will give it a try later today. Be good not to have to use ng-file-upload which i could not get to work. Nov 8, 2015 at 12:37
  • Happy to help. :) Could you accept the answer then? Nov 10, 2015 at 5:00

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.