Angular - pass scope to service and set value - angularjs

I cannot pass/set the value to the text-area outside the controller.
I am uploading an excel and regarding the upload status I want to set some data to a text-area.
This is my code so far:
app.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl, commentArea){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
/* commentArea.append('This is not working');
commentArea = 'This is not working';
$scope.outputImportObject = 'This is not working';
*/
alert('The file was succesfully uploaded!');
})
.error(function(){
alert('There was an error while inserting the file!');
});
}
}]);
app.controller('UploadCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
$scope.outputImportObject = 'This is working';
var file = $scope.myFile;
var commentArea = $scope.outputImportObject;
fileUpload.uploadFileToUrl(file, ws_url+'upload_excel.php',commentArea);
};
}]);

This typically seems a case where you should be using promises.
From your services you should return a promise and based on their resolution or rejection, you should bind the variable on controller.
your service should look something like:
app.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl, commentArea){
var fd = new FormData();
fd.append('file', file);
return
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
}
}]);
Since, http itself return a promise, you can directly return it, instead of making your custom promise.
and your controller should be like:
app.controller('UploadCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
$scope.outputImportObject = 'This is working';
var file = $scope.myFile;
var commentArea = $scope.outputImportObject;
fileUpload.uploadFileToUrl(file, ws_url+'upload_excel.php',commentArea)
.then(doThisOnSuccess, doThisOnFailure);
function doThisOnSuccess(){
code for binding to text area should go here
}
function doThisOnFailure(){
}
};
}]);

Related

AngularJS: angular.js:13920 TypeError: Cannot read property 'then' of undefined

I am calling a back-end service using angularJS to upload multipart file I am encountering an error. the response comes to my service but from there I cannot get the response to my angular controller due to the above promise error.
fileUploadService:
(function() {
'use strict';
angular
.module('module')
.factory('FileUpload', FileUpload);
FileUpload.$inject = ['$http'];
function FileUpload($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(response){
})
.error(function(error){
});
}
return this;
}
})();
controller.js:
$scope.onFilesSelected = function(files) {
var uploadUrl = "/api//customer/logo";
FileUpload.uploadFileToUrl(files[0], uploadUrl).then(
function(result){
var logo = FileUpload.getResponse();
vm.setLogo(logo);
// $scope.errors = FileUpload.getResponse();
}, function(error) {
alert('error');
});
};
Your uploadFileToUrl() function has no return statement so it returns undefined. I guess you meant to return the promise returned by $http:
this.uploadFileToUrl = function(file, uploadUrl) {
var fd = new FormData();
fd.append('file', file);
// Notice the return statement below
return $http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(response){
})
.error(function(error){
});
}
You didn't return any values. So do return response inside the success and error callback as below
.success(function(response){
return response;
})
.error(function(error){
return error
});

How to set token value in headers when uploading a file angular

I am uploading a file using angular and node.js API.
I am following this link to upload a file.
In this tutorial we need to set header headers: {'Content-Type': undefined}
On other hand I need to set headers value for authentication token . For that I am setting default headers value like as $http.defaults.headers.common.Authorization = $cookieStore.get('token');
Now when I uploading a file then a error is shwoing i.e
Error: Can't set headers after they are sent.
Now please let me know how can I resolve this..
Or any solution to achieve this.
Thanks
Below is the Service and Controller for file upload
app.service('fileUpload', ['$http','$cookieStore', function ($http, $cookieStore) {
this.uploadFileToUrl = function(file, uploadUrl){
var token = $cookieStore.get('token') ;
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {transformRequest: angular.identity,headers: {'Content-Type': undefined} })
.success(function(res){
})
.error(function(){
});
}
}]);
app.controller('csvCtrl', function($scope, fileUpload){
$scope.importcsv=function(){
var file=$scope.myFile;
var uploadUrl="/api/parsecsv";
fileUpload.uploadFileToUrl(file, uploadUrl);
}
});
This should get you to the point of being able to apply the header:
app.service('fileUpload', ['$http', '$cookieStore', function ($http, $cookieStore) {
this.uploadFileToUrl = function (file, uploadUrl) {
var token = $cookieStore.get('token');
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd,
{
transformRequest: angular.identity,
headers: {
'Content-Type': undefined,
'Authorization': token
}
})
.success(function (res) {
})
.error(function () {
});
}
}]);
Once you get that working, you can set the default headers with an interceptor.

How can Angular Service Function return response to controller

Actually, I am uploading image using service, image uploaded successfully, but I want responded data to the function in controller.
Controller:
adminApp.controller('imageController', ['$scope', 'fileUpload', 'Images',function ($scope, fileUpload, Images) {
$scope.uploadFile = function (data) {
console.log(data);
var file = data.myFile;
console.log('file is ');
console.dir(file);
var uploadUrl = "/image";
fileUpload.uploadFileToUrl(file, data, uploadUrl);
// $scope.images.push();
};
}]);
Service:
adminApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function (file, data, uploadUrl) {
var fd = new FormData();
fd.append('file', file);
fd.append('owner_id', data.owner_id);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function (data) {
// return data;
})
.error(function () {
});
}
}]);
laravel (backhand):
public function store(Request $request)
{
$image = $request->file('file');
$image = $this->imageRepository->makeImage($image);
return $image;
}
I function in service return responded data from backhand to controller, so I can push the value to $scope.images in controllers function.
You can take advantage of angular $q here.
Updated Service Function
this.uploadFileToUrl = function (file, data, uploadUrl) {
var defer = $q.defer();
var fd = new FormData();
fd.append('file', file);
fd.append('owner_id', data.owner_id);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function (data) {
// return data;
defer.resolve(data);
})
.error(function (error) {
defer.reject(error);
});
}
return defer.promise;
}]);
In your controller, you can use the function as
fileUpload.uploadFileToUrl(file, data, uploadUrl).then(function(response){
//response contains your data form service
}).catch(function(error){
// error variable contains error data from service.
});
the code is not tested.. but it should work or very close.

Provider 'FileUpload' must return a value from $get factory method

In a web application made with AngularJs there is a page where the user can upload a file. But I have some problem.
This is the Factory that makes the upload:
angular.module('app').factory('FileUpload', ['$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(){
});
}
}]);
If I try to upload a file, console gives me this error:
"Error: [$injector:undef] Provider 'FileUpload' must return a value from $get factory method.
This is the function in the Controller:
$scope.uploadFile = function(){
var userId = $stateParams.userId;
var fileType = $stateParams.fileType;
var file = $scope.myFile;
console.log('file is ');
console.dir(file);
var uploadUrl = 'my_url';
FileUpload.uploadFileToUrl(file, uploadUrl);
};
The pattern you're using should use service not factory. With factory you want to return the new'd up instance, with service you just provide the function.
angular.module('app').service('FileUpload',...

AngularJS return a value from service

I followed this tutorial to image upload for ionic app.
https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
It works but I have one issue: in the file upload, I am returning the new filename from the server. I have to save it to a variable in the controller. I can't save the value from services to controller.
Here is my controller, services and views
Directive & Service
.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]);
});
});
}
};
}])
.service('fileUpload', ['$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(data){
alert(data);
})
.error(function(){
});
}
}])
Controller
.controller('MyCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadBtn1 = false;
$scope.uploadSpin1 = true;
$scope.uploadFile = function(){
var file = $scope.myFile;
$scope.uploadBtn1 = true;
$scope.uploadSpin1 = false;
console.log('file is ' + JSON.stringify(file));
var uploadUrl = "http://example.com/app/upload.php";
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
HTML
<input type="file" file-model="myFile"/>
<button type="button" ng-click="uploadFile()"
ng-hide="uploadBtn1" class="ng-hide">upload me</button>
<ion-spinner icon="ios-small" ng-hide="uploadSpin1" class="ng-hide"></ion-spinner>
I also added the loading spinner when the upload starts and I want to hide it when the upload ends.
Thanks
I have made a few changes to the example in question. The service is now implemented as a factory which returns a promise.
You can then wait in your controller for the promise to return and then handle the data in your controller.
codepen example
var uploadFile = fileUpload.uploadFileToUrl(file, uploadUrl);
uploadFile.error(function(data){
alert('data returned - handle me', data);
});
In my example, I have changed the returned data to a string and passed this back to the controller which then alerts the user of this data.

Resources