Search code examples
javascriptangularjsif-statementtoastr

how to customize angular toaster message


I am using angular-file-upload. I have setup a batch file upload that parse's the file names and matched them to properties stored in a database. The files need to be structured like this.

01-1998 VRF RD678.pdf

VRF is the name of a pipeline RD is the name of a location 678 is the number of a location code

they each have there own if statement to check for files that do match anything in the database. right now if something does not match or is named improperly this appears errorPic

I would like to do 3 things.

  1. define a error message that shows the file name and the specific if statement that errors out. if there is no match for the pipeline i want the file name and "no match for pipeline" underneath.

  2. define a error message for when the structure of the file name is incorrect. i want the file name with "incorrect filename" underneath

  3. prevent the function from error out, I would like the error messages to be displayed and allow the other files to be uploaded

I am trying to use linq.js, javascript is ok as well.

here is what i am trying to make work, this example is when a file is not structured correctly. this error message is

TypeError: Cannot read property 'name' of undefined

$scope.upload = function () {
    var files = $scope.files;
    if (files && files.length) {
        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            $scope.pipes.map(function (pip) {
                $scope.pipeLookup[pip['PipeAb']] = pip;
            });
            $scope.locations.map(function (loc) {
                $scope.locationLookup[loc['LocationAb']] = loc;
            });
            $scope.locationCodes.map(function (locCode) {
                $scope.locationCodeLookup[locCode['LocationCodeAb']] = locCode;
            });
            var matchesPip = file.name.match(/^\d+\D\d+\s*(\S*\s*)(\S*)/i);
            var matchesLoc = file.name.match(/^\d+\D\d+\s*?(\S*)\s*(\S*?)(\d+)\./i);
            var matchesLocCode = file.name.match(/^(\d+\D\d+)\s*?(\S*)\s*(\S*?)(\d+)\./i);
            $scope.pip = $scope.pipeLookup[matchesPip[1]];
            $scope.loc = $scope.locationLookup[matchesLoc[2]];
            $scope.locCode = $scope.locationCodeLookup[matchesLocCode[4]];
            if ($scope.pip == null) {

                $scope.pip = Enumerable.From(files)
                            .Where("x => x.files.name != '" + matchesPip[0] + "'").ToArray();

                toaster.pop('error', matchesPip[0]);
                console.log(matchesPip[0])
            }
            if ($scope.loc == null) {
                toaster.pop('error', matchesLoc[0]);
                console.log(matchesLoc[0])
            }
            if ($scope.locCode == null) {
                toaster.pop('error', matchesLocCode[0]);
                console.log(matchesLocCode[0])
            }
            $upload.upload({
                url: '/api/apiBatchPipeLine',
                fields: {
                    'typeId': 1,
                    'companyId': $scope.companyId.CompanyId,
                    'companyName': $scope.companyId.CompanyName,
                    'documentDate': $scope.model.documentDate,
                    'pipeId': $scope.pip['PipeId'],
                    'pipeName': $scope.pip['PipeName'],
                    'locationId': $scope.loc['LocationId'],
                    'locationAb': $scope.loc['LocationAb'],
                    'locationCodeId': $scope.locCode['LocationCodeId'],
                    'locationCodeAb': $scope.locCode['LocationCodeAb']
                },
                file: file
            }).progress(function (evt) {
                var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name);
            }).success(function (data, status, headers, config) {
                toaster.pop('success', config.file.name);
                console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
            }).error(function (err, result, config) {
                toaster.pop('error', config.file.name);
                console.log(err, result);
            });

        }
    }
};

pic2 pic1


Solution

  • ngFileUpload error event callback receives 4 arguments as in:

    https://github.com/danialfarid/ng-file-upload/blob/master/dist/ng-file-upload-all.js#L509-514

    promise.error = function (fn) {
       promise.then(null, function (response) {
           fn(response.data, response.status, response.headers, config);
       });
       return promise;
    };
    

    headers is the 3rd argument, config is the 4th argument. In your code config is referencing headers. headers.file is undefined so this is how you get the error TypeError: Cannot read property 'name' of undefined.

    Change:

    .error(function (err, result, config) {
       ...
    })
    

    To:

    .error(function (err, result, headers, config) {
       ...
    })