I am building a mobile app using ionic. One of the usecase is to let the user browse a file and upload it to the backend server (which exposes a rest service).
On the UI, I am using the html file tag
<input type="file" ng-select="uploadFile($files)" multiple>
This opens a file browser to select a file. Then in the controller, I am doing the following
.controller('UploadDocCtrl', function ($scope, $cordovaFileTransfer) {
$scope.uploadFile = function(files) {
console.log("selected file "+files);
// hard coded file path "/android_asset/www/img/ionic.pdf" to be replaced with the user selected file
$cordovaFileTransfer.upload(restServiceEndpoint, "/android_asset/www/img/ionic.pdf", properties).then(function(result) {
console.log("SUCCESS: " + JSON.stringify(result.response));
}, function(err) {
console.log("ERROR: " + JSON.stringify(err));
}, function (progress) {
// constant progress updates
});
});
The problem is that I am not able to get a reference to the selected file. Can someone please help with the steps to achieve this. Thanks!
Related
Am trying to use integrate oauth in my Hybrid app and am using angularjs 1 with cordova. I tried using this plugin
https://github.com/EddyVerbruggen/cordova-plugin-safariviewcontroller along with
https://github.com/EddyVerbruggen/Custom-URL-scheme
But its not straight forward and clear for me.
Am facing two issues
Unable to redirect to app after oauth is done.
How to close the chrome custom tab and get the data in the app after oauth is done.
Below is what am trying.
Client Side Code:
var options=[{url:oauthPostURL,hidden:false,animated:false}];
$scope.openUrl = function(options) {
console.log("inside openurl--");
var deferred = $q.defer();
try{
cordova.exec(
// success function
function(response){
deferred.resolve(response);
},
//failure function
function(response){
deferred.resolve(false);
},
"ChromeCustomTabPlugin", "show", options);
}catch(e){
console.log("error in corodva plugin ::"+e);
}
return deferred.promise;
}
function handleOpenURL(url) {
setTimeout(function() {
//SafariViewController.hide();
var data = decodeURIComponent(url.substr(url.indexOf('=')+1));
console.log('Browser data received: ' + data);
}, 0);
}
who will call this handleopenurl function ?
In the plugin there is no method for hide() to close the chrome custom tab
ServerSide :
Am using ChromeCustomTabPlugin.java from the plugin mentioned above
Please help am struggling from 2 days. It would be great if some one can provide end-to-end example
I solved it Myself.
There are several mistakes done.
I added custom-url-schema plugin manually.
HandleopenUrl function to be placed in page which is global, i placed
the function in index.html which is my starting page.
LaunchMyApp.java file which is inside custom-url-plugin was missing
launchMyApp.js file was missing.
<plugin name="cordova-plugin-customurlscheme" spec="^4.3.0">
<variable name="URL_SCHEME" value="" />
<variable name="ANDROID_SCHEME" value="" />
<variable name="ANDROID_HOST" value="" />
<variable name="ANDROID_PATHPREFIX" value="/" />
</plugin>
This lines in config.xml was missing.
I am building a mobile app using ionic. One of the usecase is to let the user browse a file and upload it to the backend server (which exposes a rest service).
On the UI, I am using the html file tag.
<input type="file" ng-select="uploadFile($files)" multiple>
.controller('UploadDocCtrl', function ($scope, $cordovaFileTransfer) {
$scope.uploadFile = function(files) {
console.log("selected file "+files);
// hard coded file path "/android_asset/www/img/ionic.pdf" to be replaced with the user selected file
$cordovaFileTransfer.upload(restServiceEndpoint, "/android_asset/www/img/ionic.pdf", properties).then(function(result) {
console.log("SUCCESS: " + JSON.stringify(result.response));
}, function(err) {
console.log("ERROR: " + JSON.stringify(err));
}, function (progress) {
// constant progress updates
});
});
The problem is that I am not able to get a reference to the selected file. Can someone please help with the steps to achieve this. Thanks!
Keep file in www folder which has index.html file.
then just give path like "ionic.pdf"
.controller('UploadDocCtrl', function ($scope, $cordovaFileTransfer) {
$scope.uploadFile = function(files) {
console.log("selected file "+files);
// hard coded file path "/android_asset/www/img/ionic.pdf" to be replaced with the user selected file
$cordovaFileTransfer.upload(restServiceEndpoint, "ionic.pdf", properties).then(function(result) {
console.log("SUCCESS: " + JSON.stringify(result.response));
}, function(err) {
console.log("ERROR: " + JSON.stringify(err));
}, function (progress) {
// constant progress updates
});
});
I was writing E2E test-case using protractor for angularjs application. My application has multiple file uploading as one of its features. So, to write E2E test-case for my application, I have to automate multiple file-uploading.
I am able to upload single file using protractor but my application requires more than 1 file for seamless working.
browser.get(localUrl);
var button = element(by.css('[ngf-select]'));
button.click();
var input = element(by.css('input[type="file"]'));
input.sendKeys([ absolutePath, absolutePath1, absolutePath2]);
Regards
Ajay
Have you tried
browser.get(localUrl);
var button = element(by.css('[ngf-select]'));
button.click();
var input = element(by.css('input[type="file"]'));
input.sendKeys( absolutePath + "\n" + absolutePath1 + "\n" + absolutePath2);
Your requirement seems to be like Data Driven approach. So, keep all input file paths in below function arrayOfData() and it block will iterate till all files are uploaded. You can follow the below code:
describe('Data driven test spec', function () {
function arrayOfData() {
return [
{
"absolutePath": "/PathToFile1",
},
{
"absolutePath": "/PathToFile2",
},
{
"absolutePath": "/PathToFile3",
},
]
}
beforeAll(function(){
browser.get(localUrl);
})
using(arrayofData, function (inputData) {
it('test case logic to be executed for each set of data', function () {
var button = element(by.css('[ngf-select]'));
var input = element(by.css('input[type="file"]'));
button.click();
input.sendKeys(inputData.absolutePath);
});
});
});
I am trying to make a post request using Google Cloud Endpoints and AngularJS when the page loads so I can get the user information and fill the profile picture, profile description and so on...
I am able to run requests when pressing a button or something like that but can't call the google endpoints automatically when the page loads and that is whats I am trying to achieve.
Below is the HTML part where the {{userPicture}} should've been loaded in the angular script:
(HTML)
<div class="form-group">
<label class="col-sm-3 control-label">Profile image</label>
<div class="col-sm-9" ng-controller='initController'>
<img src="{{userPicture}}" class="user-image-profile" alt="User Image">
</div>
</div>
(ANGULAR)
controllers.initController = function($scope, $http){
$scope.userForm = {
"userEmail" : $.cookie('auth')
};
gapi.client.igardenendpoints.getProfile($scope.userForm).execute(function(resp) {
$scope.$apply(function () {
if (resp.error) {
$scope.backmessage.messagetext = "GetProfile Error!"
console.log("error");
} else {
if (resp.userEmail == "TEMPLATE"){
$scope.backmessage.messagetext = "Error please try again!"
}else{
$scope.userPicture = 'https://filiperebollo1986.appspot.com/serve?blob-key=' + resp.profilePicKey;
}
}
});
});
}
error
I also tried to use the following:
$scope.initData = function () {
gapi.client.igardenendpoints.getProfile($scope.userForm)...........
}
and run the function at the end of the controller, like:
$scope.initData();
But both does not work, any help on that?
I will not be able to help you in 100% as I'm not using Google Cloud, but will try to do my best.
First of all, to get the data it's usually better to use services rather than do it in the controller.
But anyway, your problem seems to be different. In your HTML did you include your script and client API?
I was able to fix my problem and bellow is the solution:
The problem was that at the moment of my call, the script may not have been loaded once I was using the "ng-app" directive directly on the body TAG.
Now I am injecting the angular module dinamicaly just after my API loading:
function googleOnLoadCallback(){
var apisToLoad = 1; // must match number of calls to gapi.client.load()
var gCallback = function() {
if (--apisToLoad == 0) {
//Manual bootstraping of the application
var $injector = angular.bootstrap(document, ['authModule']);
console.log('Angular bootstrap complete ' + gapi);
};
};
gapi.client.load('igardenendpoints', 'v12', gCallback, '//' + window.location.host + '/_ah/api');
}
</script>
<script src="https://apis.google.com/js/client.js?onload=googleOnLoadCallback"></script>
And now It is working!!!!
The only problem now is that when the page loads it appears the {{example}} in the page, is it possible to avoid the {{}} to appear?
Is there a way to get name, path and size of selected file in input field using angularJS,
before uploading it?
<input type="file" ng-model="fileContent" on-read-file="showContent($fileContent)" />
$scope.showContent = function($fileContent){
$scope.content = $fileContent;
};
Can anyone help to solve this please?
The HTML5 File API will give you a File object for each file that you're attempting to upload. This File object will have a size and name property which will give you the file size in bytes and the name of the file.
There's no property for the physical path to the file on the users machine, though.
You can read more about this on MDN: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
More information on the File object here: https://developer.mozilla.org/en-US/docs/Web/API/File
Here's a working example: http://jsfiddle.net/fmeLz9cd/
Given an input of type file with an id fileSelected, here's an example of accessing the properties through the File API:
$('#fileSelected').on('change', function (evt) {
var files = $(evt.currentTarget).get(0).files;
if(files.length > 0) {
$('#fileName').text(files[0].name);
$('#fileSize').text(files[0].size);
$('#filePath').text($('#fileSelected').val());
}
});
Update
Since you've requested an AngularJS specific example, here's the same code working in an angular app:
http://jsfiddle.net/vyc6jq84/1/
<div ng-app="fileDemo">
<input type="file" fd-input />
</div>
var app = angular.module('fileDemo', []);
app.directive('fdInput', [function () {
return {
link: function (scope, element, attrs) {
element.on('change', function (evt) {
var files = evt.target.files;
console.log(files[0].name);
console.log(files[0].size);
});
}
}
}]);
You cannot, unless the server helps. Angular is running in your browser, and cannot read the filesystem of the server or of the browser's computer. If you want to get a file, you need the server to implement something that will do so.
Now, if it is a static file, and already is served up by the server, then you could read it via $http.
$http.get(filename).success(function(data){
// data contains the file content
});
But it may be interpreted based on the file type, etc. And this entirely presumes the file is already being served by the server.