Search code examples
javascriptangularjs

TypeError: Cannot read properties of undefined in angular JS application


I have created an angular JS app , basically i am trying to upload a file . The page gives an option to select CSV. then there is upload button. Once click it will call java function and upload the file. however, i am getting an error. Mypage.xhtml looks like this where i have added all the code.

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>CSV Upload</title>
    <!--<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>-->
   <!-- <script src="app.js"></script>-->
    <script src="#{plugins.requestContextPath}/plugin/apponboarding/ui/js/jquery.min.js" />
    <script src="#{plugins.requestContextPath}/plugin/apponboarding/ui/js/angular.min.js"></script>
    <script src="#{plugins.requestContextPath}/plugin/apponboarding/ui/js/apponboardingModule.js"></script>
    <script src="#{plugins.requestContextPath}/plugin/apponboarding/ui/js/bootstrap.min.js" />
</head>
<body ng-app="csvApp" ng-controller="CsvController">
    <h1>Upload CSV File</h1>
    <input type="file" file-model="myFile"/>
    <button type="button" ng-click="uploadFile()">Upload</button>

<script>
// app.js
var app = angular.module('csvApp', []);

app.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]);
                });
            });
        }
    };
}]);

app.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file, uploadUrl){
        var fd = new FormData();
        fd.append('file', file);
        console.log("inside service");
        $http.post(uploadUrl, fd, {
            transformRequest: angular.identity,
            headers: { 'Content-Type': undefined }
        })
        .then(function(response){
            console.log("File uploaded successfully");
        }, function(error){
            console.log("Error uploading file");
        });
    }
}]);

app.controller('CsvController', ['$scope', 'fileUpload', function($scope,$http, fileUpload){
    $scope.uploadFile = function(){
        var file = $scope.myFile;
        console.log('file is ' );
        console.dir(file);
        var REST_BASE_URL = PluginHelper.getPluginRestUrl("apponboarding");
        console.log('BASE URL is ' );
        console.log(REST_BASE_URL);
        var uploadUrl = REST_BASE_URL+ "/upload";
        console.log('uploadUrl URL is ' );
        console.log(uploadUrl);
        console.log(fileUpload);
        fileUpload.uploadFileToUrl(file, uploadUrl);
        console.log("Controller END");
    };
}]);
</script>
</body>
</html>

But when i click on upload i get an error,

TypeError: Cannot read properties of undefined (reading 'uploadFileToUrl')
    at $scope.uploadFile (pluginPage.jsf?pn=apponboarding:1511:20)
    at fn (eval at compile (angular.min.js:239:266), <anonymous>:4:150)
    at e (angular.min.js:284:187)
    at b.$eval (angular.min.js:148:347)
    at b.$apply (angular.min.js:149:52)
    at HTMLButtonElement.<anonymous> (angular.min.js:284:239)
    at HTMLButtonElement.dispatch (jquery.min.js:3:10316)
    at q.handle (jquery.min.js:3:8343)

The file should be uploaded using the java code below

@PostMapping("/upload")
        public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
            if (file.isEmpty()) {
                log.error("New Function- Empty File Detected-");
                return new ResponseEntity<>("No file uploaded.", HttpStatus.BAD_REQUEST);
            }

            try {
                // Save the file to the server
                log.error("New Function- File Detected-");
                String uploadDir = "uploads/";
                File uploadFile = new File(uploadDir + file.getOriginalFilename());
                file.transferTo(uploadFile);

                return new ResponseEntity<>("File uploaded successfully.", HttpStatus.OK);
            } catch (IOException e) {
                return new ResponseEntity<>("Error uploading file.", HttpStatus.INTERNAL_SERVER_ERROR);
            }

Solution

  • The argument order is wrong, in the array, you are missing $http which is expected inside the function.

    Before:

    app.controller('CsvController', ['$scope', 'fileUpload', function($scope,$http, fileUpload){
    

    After:

    app.controller('CsvController', ['$scope', '$http', 'fileUpload', function($scope,$http, fileUpload){
    

    OR

    app.controller('CsvController', ['$scope', 'fileUpload', function($scope, fileUpload){