ngCordova in Angular JS Web Application - angularjs

I am not an expert in Angular and have recently started learning it, I am trying to create a responsive form in an AngularJS WEB APPLICATION which will let me upload a file or a photo from a mobile browser (not mobile app). Before I upload anything through my mobile browser, I should check the native settings of my mobile device (not browser settings but the settings of my mobile device).
To achieve this I am using ngCordova with it's wrapper $cordovaFileTransfer. I have a normal project in Eclipse and I have included below files in my index page(I have stored these files locally in my project).
cordova.js
file.js
fileTransfer.js
ng-cordova.js
ng-cordova.min.js
Since I am using Eclipse, I tried to install THyM plugin however it wouldn't install in my work space. Below is my controller code.
angular.module('app').controller(
'CordovaCtrl',
function($scope, $timeout, $cordovaFileTransfer) {
document.addEventListener("deviceready", function(
$cordovaFileTransfer) {
alert("Inside the Cordova Controller - deviceready");
var fileToUpload = "";
var options = {
fileKey : "sendFile",
fileName : "angularJSFileToUpload",
chunkedMode : false,
mimeType : "text/plain"
};
var server = "C:/Dev/Angular file receiver";// Temporary path
var targetPath = "C:/Dev/Angular file sender";// Temporary path
$cordovaFileTransfer.upload(server, targetPath, options).then(
function() {
alert("Success");
}, function(err) {
alert("Error");
});
}, false)
});
I understand that all plugin calls should be wrapped in the "deviceready" event. Whenever I run my project I get below error on the browser console.
Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:8080/fileupload/cordova/cordova_plugins.js
Uncaught TypeError: Object #<Event> has no method 'upload' app.js:46
I am not sure where the cordova_plugins.js gets fetched from. I had read on some forum that it gets generated at run time (I might be wrong).
Does anyone have any idea about what’s going wrong here? I reckon I am missing something on the configuration part. Is it even possible to use ngCordova in a web application since supposedly its meant for mobile development?

Try code below
angular.module('app')
.controller('CordovaCtrl', function($scope, $timeout, $cordovaFileTransfer) {
document.addEventListener("deviceready", function() {
alert("Inside the Cordova Controller - deviceready");
var fileToUpload = "img.png";
var options = {
fileKey : "sendFile",
fileName : "angularJSFileToUpload",
chunkedMode : false,
mimeType : "text/plain"
};
var server = "C:/Dev/Angular file receiver";// Temporary path
var targetPath = "C:/Dev/Angular file sender";// Temporary path
$cordovaFileTransfer.upload(server, targetPath, options)
.then(function(result) {
alert("Success");
}, function(err) {
alert("Error");
}, function(progress){
alert("In Progress");
});
}, false)
});

Related

angular-pdfjs-viewer - Message: stream must have data

I am struggling to get angular-pdfjs-viewer working in my angular app that's written in Typescript.
I am always getting a red error message with the text:
PDF.js v1.7.354 (build: 0f7548ba)
Message: stream must have data
The PDF data is coming from an ASP.NET WebAPI controller, and the architecture of our application has the front facing website and the API both deployed as two independent web applications.
Due to this, I am wanting to download the PDF in the angular controller, and set the PDF source to the data attribute of the directive.
The WebAPI returns the PDF like this:
[HttpGet]
[Route("invoice/{id}/originalpdf")]
public async Task<ActionResult> GetInvoiceSourceImagePdf(string id)
{
var userId = User.Identity.GetMyId();
var bytes = await _serviceThatReturnsByteArray(id);
return File(bytes, System.Net.Mime.MediaTypeNames.Application.Pdf);
}
I don't see an issue with the above. In the browser, if I hit this endpoint, I get the document rendering exactly as expected.
On the front-end side:
We're using the angular-pdfjs-viewer from https://github.com/legalthings/angular-pdfjs-viewer
We're including (via BundleConfig), sources in the order of: pdf.js, then angular.js and then finally angular-pdfjs-viewer.js (with other application required dependencies in between)
I am using the PDF.js dependency that "ships" with angular-pdfjs-viewer.js
The angular controller looks like this:
module MyApp {
class PdfDialogController {
public static $inject = ["$scope", "$window", "$log", "$uibModalInstance", "$http"];
pdfData: Uint8Array;
constructor(/*stuff*/){
this.$http.get(the_url, { responseType: 'arrayBuffer' })
.then((t) => {
this.pdfData = new Uint8Array(<ArrayBuffer>t.data);
});
}
}
}
And in the view, we have:
<div class="modal-body">
<div id="pdf-container">
<pdfjs-viewer data="vm.pdfData"></pdfjs-viewer>
</div>
</div>
Inspecting the network in the browser, the PDF content is downloaded.
t.data in the controller contains data that starts with
%PDF-1.3\n%����\n1 0 obj\n[/PDF /Text]
However, the views shows this:
And the console outputs an error message:
Error: An error occurred while loading the PDF.
What am I doing wrong, and how can I determine what the issue is with the PDF data (if there is one).
Well, it turns out that I was using
{ responseType: 'arrayBuffer' } // camel case
when I should be using
{ responseType: 'arraybuffer' } // all lowercase
Once changed, the code I posted in the question worked perfectly.

Ionic http get request (with Ionic) returns html data

I am using Ionic and making http request like this:
$http.get('//GLOBAL.IP/?username=' + username + '&content_type=json')
.then(function (result) {
$scope.days = [];
alert(JSON.stringify(result));
for (first in result.data.weeks) break;
var currentWeek = result.data.weeks[first];
var time = currentWeek.overall.as_time;
$scope.week = currentWeek;
for (day in currentWeek.days.sort().reverse()) {
if (day < 2) {
continue;
}
var currentDay = currentWeek.days[day];
$scope.days.push(currentDay);
if (currentDay.present) {
console.log(parseInt(currentDay.work_time_balance) + parseInt(currentWeek.overall.seconds));
}
}
}, function (result) {
alert(JSON.stringify(result));
$ionicPopup.alert({
title: 'Error',
template: 'Connection failed, try again later!'
});
})
.finally(function () {
// Stop the ion-refresher from spinning
$scope.$broadcast('scroll.refreshComplete');
});
While I am opening app in browser with command ionic serve, everything seems working okay, I've already fixed CORS and other stuff.
But when In mobile app, I am getting this (sorry for not providing plaintext)
UPDATE
$http.get('//GLOBAL.IP/?username=' + username + '&content_type=json')
.then(function (result) {
alert('Good');
}, function (result) {
alert('Bad');
})
This code returns me GOOD, but result.data is still with script tags.
When you are testing this app in working mode what is localhost, Its a local server running on same machine, right.
When you install or run app in your mobile device where it is pointing to? Do you know that, If code is okay then replacing localhost with IP of your machine should resolve this issue.
Many script tags with addRow in ionic http request response, was because of // in the beginning of uri, protocol was selecting successfully in browser, but not in compiled app.

Facebook login on mobile via Cordova/Angular/Ionic

I'm working in a hybrid app to report potholes in our city.
The user can register to the app in a classic way (fill forms) or via one of the social networks (facebook, gmail, twitter).
The system works through a server on rails and a mobile app as a client(ionic/angular)
On the server side we have solved this, the user can make sign up / sign in to the page in the way that they want.
But with have several problems with the app, the app does nothing when you make click to the button of "sign in via facebook"
this is the style it is organized.
app/
plugins/
InAppBrowser
www/
css/
js/
controllers/
splash.js
map.js
tabs.js
services/
users.js
notifications.js
app.js
utils.js
lib/
angular/
ng-cordova-oauth/
ngCordova/
ionic/
templates/
map.html
splash.html
tabs.html
index.html
The splash.js controller is in charge of making the login function.
angular.module('app')
.controller('SplashCtrl', function($scope, User, $state, $ionicPopup, $auth, $cordovaOauth) {
$scope.session_id = User.session_id;
$scope.facebookLogin = function() {
alert("flag1");
User.fbSignIn().then(function() {
alert("flag2");
User.fbGetData().then(function() {
alert("flag3");
User.fbAuth().then(function() {
alert("flag4");
// Detect if it is a sign in or sign up
if (User.username) {
console.log('Controller reports successfull social login.');
$state.go('tab.map');
} else {
// Open finish signup modal
console.log('Contorller reports this is a new user');
$state.go('finish_signup');
}
}, function() {
alert("flag5");
$ionicPopup.alert({
title: '<b>App</b>',
template: 'Credenciales no válidas, vuelve a intentar.',
okText: 'Aceptar',
okType: 'button-energized'
})
});
}, function() {
alert("flag6");
// alert('Could not get your Facebook data...');
});
}, function() {
alert("flag7");
// alert('Could not sign you into Facebook...');
});
}
})
I put some alert flags through the functions to see where the app get stuck.
I can only see the 'flag1' alert on the phone.Then nothing happens
the controller communicates with the service users.js
I put the code on pastebin because it's too long
users.js service
The client must request an access token to the server and then compare in SplashCtrl if they got the token access the app redirects the user to tabs.html template that would be the main page.
The console server shows nothing. So the request application never communicates to the server. Eventhough the 'CLIENTS' and 'SERVER' variables are already declared in app.js
.constant('SERVER', {
url: 'https://rails-tutorial-denialtorres.c9.io'
})
.constant('CLIENTS', {
facebook: 'fb Api'
});
I can only logging of the server if I put a username and password in a traditional way
preview
I hope you can help me with this guys
regards and thanks!!
you try this ?
http://ngcordova.com/docs/plugins/oauth/
I tested and work very well, easy to implement, and also you can parse the json with token (and use server side if you need)
Remember this work ONLY with real device, not with Ionic Serve.
In case you looking for custom facebook login (javascript), try this code :
facebookStatus = function() {
var dfd = new jQuery.Deferred();
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
dfd.resolve({status: response.status, token: response.authResponse.accessToken});
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook, //but not connected to the app
dfd.resolve({status: response.status, token: false});
} else {
// the user isn't even logged in to Facebook.
FB.login(function(response) {
if (response.status=="connected"){
var token = response.authResponse.accessToken;
dfd.resolve({status: response.status, token: response.authResponse.accessToken});
}
}, {scope:'YOUR SCOPE HERE'});
}
});
return dfd.promise();
};
*Remember if you use this code, to add on index page the standard Facebook App details (something like)
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR APP ID',
status : true, // check login status
cookie : false, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
};
// Load the SDK asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
When I install the cordova plugin with add org.apache.cordova.inappbrowser
The id for the plugin is cordova-plugin-inappbrowser and the ngcordova.js library is looking for org.apache.cordova.inappbrowser
Changing those lines on ngcordova.js solves the issue.

Cordova FileTransfer: upload image to AWS s3

Am using ng-cordova file-Transfer plugin to upload images to my AWS s3 bucket.
but i run into two problems first it didn't work, second i have no idea how to debug the problem while the App running on the emulater.
here is my code:
.controller('newItemCtrl', function($scope, $http, API_URL, me, $cordovaFileTransfer) {
var s3URI = encodeURI("https://mybucketname.s3.amazonaws.com/"),
policyBase64 = "MY_BASE64_ENCODED_POLICY_FILE",
signature = "MY_BASE64_ENCODED_SIGNATURE",
awsKey = 'my AWSAccessKeyId',
acl = "public-read";
var options = {
fileKey: "avatar",
fileName: "image.png",
chunkedMode: false,
mimeType: "image/png"
// params = {
// "key": fileName,
// "AWSAccessKeyId": awsKey,
// "acl": acl,
// "policy": policyBase64,
// "signature": signature,
// "Content-Type": "image/png"
// }
};
var imageURI = '../img/ionic.png';
$scope.upload = function($cordovaFileTransfer) {
$cordovaFileTransfer.upload(s3URI, imageURI, options)
.then(function(result) {
console.log("SUCCESS: " + JSON.stringify(result.response));
}, function(err) {
console.log("ERROR: " + JSON.stringify(err));
}, function(progress) {
// constant progress updates
});
}
})
I also left the params code to ask another question it's commented, but before i run my app and it gives me an error with the params but my question why i got the error even before invoke the template assosiated with that controller
I had a similar problem, to debug I used the live server logs to check and see if the file upload hit the server at all, some errors I noticed:
my server was expecting a different file key
the Access-Control-Allow-Origin header wasnt being sent properly in the server's response
Then, I also installed the cordova native notifications plugin (link here) and sprinkled alerts throughout the file transfer callbacks to see where things were getting stuck
Anyway probably not the best way to debug, but it worked.
Hope that helps.
...one more thing the params part of "options" seems to work best when applied in this format:
var options = {
fileKey: "avatar",
fileName: "image.jpg",
/*params: {
"value1":"value1",
"value2": "value2"
}*/
};
var params = new Object();
params.value1 = "value1";
params.value2 = "value2";
options.params = params;
from the cordova docs "params: A set of optional key/value pairs to pass in the HTTP request. (Object)" so passing in a dictionary may be subtly different, I'm not sure, all I know is that it worked once I made that change.
To debug on emulator I use this from my app directory: ionic emulate ios -lc
That shows me errors or logs into the console.

Cross origin request not working in Cordova with AngularJS

I am developing mobile application with Cordova tool and using angularJS.
I have written services in different project. I need to call those services in my cordova application, Whenever I try to call service it giving me Error:
net::ERR_CONNECTION_REFUSED
This might be browser issue or headers issue. Please suggest me right way to solve this issue.
Currently I am running service on localhost, and It is working perfectly when I call them from fiddler.
I have also open CORS in service project.
JodoModule.service("AccountSrv", function ($http) {
this.signUp = function (user) {
var SignUpReq = {
method: 'GET',
url: 'http://localhost:62676/api/Account/signin'
}
$http(SignUpReq).success(function () { alert("Succ"); }).error(function (data) { alert("Err = " + JSON.stringify(data)); });
}
});
and my controller is,
JodoModule.controller("AccountCtrl", function ($scope, AccountSrv) {
$scope.signUp = function () {
AccountSrv.signUp();
}
});
You can disable cross domain proxies in the emulator as a workaround.

Resources