Valor_ Valor_ - 3 months ago 289
AngularJS Question

Http request configuration url must be a string. Received: undefined

I just moved my upload function from controller (where it was working as it should) to factory and it sudenly stopped working. I'm keep getting this error, but i don't know/understand where the problem is

angular.js:13550 Error: [$http:badreq] Http request configuration url must be a string. Received: undefined
http://errors.angularjs.org/1.5.5/$http/badreq?p0=undefined
at angular.js:68
at $http (angular.js:11194)
at uploadWithAngular (ng-file-upload.js:91)
at sendHttp (ng-file-upload.js:144)
at upload (ng-file-upload.js:330)
at Scope.$scope.uploadDocument (locationsCtrl.js:131)
at fn (eval at compile (angular.js:14432), <anonymous>:4:338)
at expensiveCheckFn (angular.js:15485)
at callback (angular.js:25018)
at Scope.$eval (angular.js:17229)


This is my upload document function in controller

$scope.uploadDocument = function(file) {
if($scope.documentName.length > 4) {
$scope.errorMsg = '';
file.upload = Upload.upload( documentsFactory.uploadDocument(
$scope.id_location,
$scope.documentName,
$scope.documentDescription,
file,
$scope.locationUniqueId
));
file.upload.then(function (response) {
$scope.documentName = $scope.documentDescription = $scope.userFile = '';
documentsFactory.getDocuments($scope.id_location).then(function (data) {
$scope.documents = data;
});
$timeout(function () {
file.result = response.data;
});
}, function (response) {
if (response.status > 0)
$scope.errorMsg = response.status + ': ' + response.data;
}, function (evt) {
// Math.min is to fix IE which reports 200% sometimes
file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
}else{
$scope.errorMsg = 'Name should be at least 5 chars long';
}
};


And this is my factory

factory.uploadDocument = function(id_location, name, description, file, locationUniqueId){
return $http({
method: 'POST',
url: $location.protocol() + '://' + $location.host() + '/rest/api/document/documents',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: {
id_location: id_location,
name: name,
description: description,
userFile: file,
locationUniqueId: locationUniqueId
}
}).then(function successCallback(response){
return response.data;
},function errorCallback(response){
console.log('Error uploading documents: ' + response);
});
};


UPDATE:
This is working example if i make "upload request" in my controller

file.upload = Upload.upload({
url: $location.protocol() + '://' + $location.host() + '/rest/api/document/documents/',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: {
id_location: $scope.id_location,
name: $scope.documentName,
description: $scope.documentDescription,
userFile: file,
locationUniqueId: $scope.locationUniqueId
}
});


If you need any additional inflammations please let me know and i will provide. Thank you in advance

Answer

Following the error stack:

From ng-file-upload repository.

this.upload = function (config, internal) {

which is called by you there

 Upload.upload( documentsFactory.uploadDocument(
        $scope.id_location,
        $scope.documentName,
        $scope.documentDescription,
        file,
        $scope.locationUniqueId
    ));

line 330

return sendHttp(config);

line 144

uploadWithAngular();

line 91

$http(config).then(function (r) {

Where the error gets thrown. It looks like Upload.upload doesn't accept a promise, but a config for the $http call.


EDIT

What about returning the config object?

factory.uploadDocument = function(id_location, name, description, file, locationUniqueId){
    return {
        method: 'POST',
        url: $location.protocol() + '://' + $location.host() + '/rest/api/document/documents',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        data: {
            id_location: id_location,
            name: name,
            description: description,
            userFile: file,
            locationUniqueId: locationUniqueId
        }
    }
};

The best idea would be to move Upload to the factory and return the promise.

factory.uploadDocument = function(id_location, name, description, file, locationUniqueId){
    return Upload.upload({
        method: 'POST',
        url: $location.protocol() + '://' + $location.host() + '/rest/api/document/documents',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        data: {
            id_location: id_location,
            name: name,
            description: description,
            userFile: file,
            locationUniqueId: locationUniqueId
        }
    });