I would like to send a picture from Ionic app to Laravel back-end, but I keep getting FileTransferError.FILE_NOT_FOUND_ERR (Code=1) in the app.
Taking picture works:
$scope.openCamera = function () {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
navigator.camera.getPicture(onSuccess, onFail, {
quality: 50,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: 1, // 0:Photo Library, 1=Camera, 2=Saved Photo Album
encodingType: 0 // 0=JPG 1=PNG
});
function onSuccess(FILE_URI) {
$scope.picData = FILE_URI;
$scope.$apply();
}
function onFail(message) {
alert('Error (' + message + ')');
}
}
}
But sending keeps throwing error:
$scope.send = function () {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
var myImg = $scope.picData;
var options = new FileUploadOptions();
options.fileKey = "post";
options.chunkedMode = false;
options.fileName = 'someFileName.jpg';
options.mimeType = "image/jpeg";
var params = {};
params.token = localStorage.getItem('token');
options.params = params;
var ft = new FileTransfer();
ft.upload(myImg, encodeURI(SERVER + 'user/post'), win, fail, options);
}
}
I have noticed that when I look at the error.source that I can't find physically the file listed. I can't debug on browser (lack of camera) so I am deploying everything to my phone.
var fail = function (error) {
alert("An error has occurred: Code = " + error.code);
alert("upload error source " + error.source);
//alert("upload error target " + error.target);
}
well, i had this problem and i found a solution, a bit late, but will helps, someone:
var headers = {'Authorization':'Bearer '+ $localStorage.get('token')};
options.headers = headers;
Related
I am having problem posting to a function in my back-end (Node.js) from my front-end (AngularJS).
I keep getting a 404 error. Could someone see if there is something wrong with my code as I can't see what may be causing this.
Front end
MockUpMaker_v1/js/controller.js
// All photos've been pushed now sending it to back end
$timeout(function () {
$http.post('/MockUpMaker_v1/savePhotos', $scope.photosToPhp).then(function (success) {
$scope.generating = false;
$scope.generateBtn = 'Generate';
//creating mock up gallery
for (var x = 0; x < success.data.photos; x++) {
var file = '/MockUpMaker_v1/tmp/' + success.data.folder + "/out" + x + ".png";
$scope.gallery.push(file);
}
$scope.photosToPhp = [];
}, function (error) {
});
},
Back end
MockUpMaker_v1/server.js
app.post('/MockUpMaker_v1/savePhotos', function(req, res){
var folder = Math.random().toString(36).substr(2, 20);
var photos = req.body;
var counts = 0;
var callback = function(counts){
if(counts < photos.length){
saveBase64(photos[counts], folder, counts, callback);
}else{
// var counts = 0;
var response = {"folder": folder, "photos": photos.length};
res.send(response)
}
};
saveBase64(photos[counts], folder, counts, callback);
});
Full back-end
As requested
"use strict";
var express = require('express');
var bodyParser = require('body-parser');
var fs = require('fs');
var mkdirp = require('mkdirp');
var archiver = require('archiver');
var app = express();
var server = require('http').Server(app);
app.use(bodyParser.json({limit: '50mb'}));
app.use(express.static('/public'));
app.use(express.static('/js'));
app.use(express.static('/tmp'));
app.use(express.static('/img'));
app.use(express.static('/css'));
app.get('/', function(req, res){
res.sendFile(__dirname + 'views/form-mockup.html')
});
app.post('/MockUpMaker_v1/savePhotos', function(req, res){
var folder = Math.random().toString(36).substr(2, 20);
var photos = req.body;
var counts = 0;
var callback = function(counts){
if(counts < photos.length){
saveBase64(photos[counts], folder, counts, callback);
}else{
// var counts = 0;
var response = {"folder": folder, "photos": photos.length};
res.send(response)
}
};
saveBase64(photos[counts], folder, counts, callback);
});
app.post('MockUpMaker_v1/downloadZip', function(req, res){
var photos = req.body;
var out = photos[0];
var test = out.split('/');
var loc = test.pop();
var end = test.join('/');
console.log(end);
var outName = '/' + end + '/MockUp.zip';
var output = fs.createWriteStream(outName);
var archive = archiver('zip', {store: true });
var zip = function(photos, f){
for(var t = 0; t < photos.length; t++){
var file = 'mockUp' + t + '.jpg';
var from = '/' + photos[t];
archive.file( from, { name: file });
}
f();
};
output.on('close', function() {
var photos = req.body;
var out = photos[0];
var test = out.split('/');
var loc = test.pop();
var end = test.join('/');
res.send(end + '/MockUp.zip');
console.log('archiver has been finalized and the output file descriptor has closed.');
});
archive.on('error', function(err) {
throw err;
});
archive.pipe(output);
zip(photos, f);
function f(){
archive.finalize();
}
});
server.listen(3000, function(){
console.log('sm2.0 server running');
});
function saveBase64(photo, folder, counts, callback){
var result = photo.split(',')[1];
var path = 'tmp/' + folder;
var filename = path + "/out" + counts + ".png";
mkdirp( path, function() {
fs.writeFile(filename, result, 'base64', function(error){
if (error) {
console.log('error saving photo');
}else{
console.log('photo saved');
counts++;
callback(counts);
}
});
});
}
And console printout
[nodemon] restarting due to changes... [nodemon] restarting due to
changes... [nodemon] starting node server.js sm2.0 server running
Inspect error
POST http://localhost:63342/MockUpMaker_v1/savePhotos 404 (Not Found)
In your Angular App, write the whole URL as the first argument of the $http.post function.
E.g. http://localhost:3000/MockUpMaker_v1/savePhotos
I want to upload 4 images from an ionic app to server side made using sails js.
An user can upload many images so before submit a form so I save all images in an array as its shown below
var cameraOptions = {
quality: 100,
destinationType: Camera.DestinationType.NATIVE_URI,
sourceType : Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 500,
targetHeight: 500,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false,
allowEdit:true
};
var success = function(data){
$mdDialog.hide();
if(key==null)
{
compteurImage =compteurImage+1;
$scope.$apply(function () {
$scope.imgURI.push(data);
});
$scope.nombreImage=compteurImage;
}
else
{
$scope.$apply(function () {
$scope.imgURI[key]=data;
});
}
$rootScope.image=$scope.imgURI;
};
After having had all the images in an array, I loop on the array and I send each image to the server as shown below
for (var i = 0; i<$rootScope.image.length; i++) {
if (keepGoing) {
var options = new FileUploadOptions();
var params = {};
params.idArticle =response.article.idArticle;
var url=$rootScope.image[i].substr($rootScope.image[i].lastIndexOf('/') + 1);
options = {
fileKey: "file",
fileName:i+(url.split('?')[0]),
mimeType: "image/png",
idArticle: response.article.idArticle
};
options.params=params;
var failed = function (err) {
console.log(err);
keepGoing = false;
};
var success = function (result) {
count++;
if(count==$rootScope.image.length)
{
console.log("success");
}
};
var ft = new FileTransfer();
ft.upload($rootScope.image[i], Globals.urlServer + Globals.port + "/article/uploadImage", success, failed, options);
}
Server side the controller in charge of upload image is /article/uploadImage
uploadImage:function(req,res)
{
req.file('file')
.upload({ dirname: '../../assets/imagesArticle'},function (err, uploadedFiles) {
if (err) return res.serverError(err);
else {
var chemin = '';
var type = '';
uploadedFiles.forEach(function (file) {
chemin = require('path').basename(file.fd);
type = file.type;
Image.create({cheminImage:chemin, typeImage:type,article:req.body.idArticle}).exec(function(err,image){
if (err)
{
res.send({success:false});
}
if(image)
{
res.send({success:true});
}
})
});
}
});
},
My issue is if regardless how many pictures I upload, when I look image directory on server side, images are always identical and correspond to the last image of the images array. For example if I upload 3 differents images, on server side I get 3 identicals images whose correspond to the third or last image in array.
how can I fix it ?
When i check all lists in table, and press delete button, A DELETE SERVICE will be called.(Using AngularJS)
Problem is, i am using a loop, and on successful delete and unsuccessful delete, i am getting alert multiple times.(No. of selection times)
And its not working properly, if place it out of loop because its Async Task.
Here is the code,
This is a controller which initiates a service.
$scope.confirmAction = function() {
var costsToDelete = [];
angular.forEach($scope.objects, function(cost) {
if (cost.selected == true) {
costsToDelete.push(cost);
}
});
$scope.deleted = true;
//need to put confirmation dialog here.
//URL: specific to timesheet deletion. it will be prefixed with constant url
var delRequestUrl = URLs.costsUrl + '/';
deleteService.deleteRecord($scope.objects, costsToDelete, delRequestUrl);
};
This is a service.
.service('deleteService', ['dataService', 'Constant.urls', 'Constants','$q','alerts',function(dataService, URLs, Constants, $q, alerts) {
var deleteService = {};
deleteService.deleteRecord = function(records, listOfRecordsToDelete, url) {
while (listOfRecordsToDelete.length > 0) {
var recordToBeDeleted = listOfRecordsToDelete.pop();
var index = listOfRecordsToDelete.indexOf(recordToBeDeleted);
var delRequestUrl = url + recordToBeDeleted.id;
var result = dataService.deleteObject(delRequestUrl);
result.success(function(data) {
Alert('success');
records.splice(index, 1);
});
result.error(function(data, status, headers, config) {
dataService.handleError(status,data);
Alert('error');
});
}
};
return deleteService; }])
I need a result like: Alert should display only once.
If all items are successfully deleted, then success or failure message.
Why dont you just create a boolean bit var status= false;//default value to true inside success callback handler and false inside error callback handler,
so once all calls are complete based on this bit you can alert success or failure
Angular JS Code:
.service('deleteService', ['dataService', 'Constant.urls', 'Constants','$q','alerts',function(dataService, URLs, Constants, $q, alerts) {
var statusBit = false; // status tracker
var deleteService = {};
deleteService.deleteRecord = function(records, listOfRecordsToDelete, url) {
while (listOfRecordsToDelete.length > 0) {
var recordToBeDeleted = listOfRecordsToDelete.pop();
var index = listOfRecordsToDelete.indexOf(recordToBeDeleted);
var delRequestUrl = url + recordToBeDeleted.id;
var result = dataService.deleteObject(delRequestUrl);
result.success(function(data) {
// Alert('success');
statusBit = true;
records.splice(index, 1);
});
result.error(function(data, status, headers, config) {
dataService.handleError(status,data);
//Alert('error');
statusBit = false;
});
if(statusBit){
Alert('success'); //console.log('successfully deleted');
}
else {
Alert('error'); // console.log('error while deleting');
}
};
return deleteService; }])
.service('deleteService', ['dataService', 'Constant.urls', 'Constants','$q','alerts',function(dataService, URLs, Constants, $q, alerts) {
var deleteService = {};
deleteService.deleteRecord = function(records, listOfRecordsToDelete, url) {
var overallResult = true;
while (listOfRecordsToDelete.length > 0) {
var recordToBeDeleted = listOfRecordsToDelete.pop();
var index = listOfRecordsToDelete.indexOf(recordToBeDeleted);
var delRequestUrl = url + recordToBeDeleted.id;
var result = dataService.deleteObject(delRequestUrl);
result.success(function(data) {
records.splice(index, 1);
});
result.error(function(data, status, headers, config) {
dataService.handleError(status,data);
overallResult = false ;
});
}
};
return deleteService; }])
I've found a couple of similar posts to this, but the answers (which boil down to putting callback=JSONP_CALLBACK into the get request) aren't working for me. Using that in the request generates an immediate 404 error, while using callback=angular.callbacks._0 at least lets the first request return a successful response. The problem is that using the very same request function with the very same params a second time to refresh the data or get the next 20 objects, returns a 404 error even though the actual get returns a 200 and the data can be seen in chrome tools.
I'm, new to using $q deferred promises, so I'm hoping that the issue has something to do with that not allowing enough time for a response before executing the reject. I'm attaching the code, which involves the Yelp API as did the other couple of posts I found on this issue. The most closely related is: (Subsequent JSONP requests give status 404 despite GET status 200), but there's another which uses the same callback string I'm using (Yelp API and AngularJS).
This particular project is for an ionic mobile app that gets coffee shops based on users geolocation.
Here's the code for the service (secret stuff removed):
var app = angular.module('caffeine.services', []);
app.service("YelpService", function ($q, $http, $cordovaGeolocation, $ionicPopup) {
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
return result;
};
var method = 'GET';
var url = 'http://api.yelp.com/v2/search';
var consumerSecret = ''; //Consumer Secret
var tokenSecret = ''; //Token Secret
var self = {
'page': 1,
'isLoading': false,
'hasMore': true,
'results': [],
'ranStr': randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'),
'timeStamp':new Date().getTime(),
'lat': 51.544440,
'lon': -0.022974,
'term': 'coffee',
'oauthConKey': '', //Consumer Key
'oauthToken': '', //Token
'oauthSigMeth': 'HMAC-SHA1',
'refresh': function () {
self.page = 1;
self.isLoading = false;
self.hasMore = true;
self.results = [];
return self.load();
},
'next': function () {
self.page += 1;
return self.load();
},
'load': function () {
self.isLoading = true;
var deferred = $q.defer();
ionic.Platform.ready(function() {
$cordovaGeolocation
.getCurrentPosition({timeout:10000, enableHighAccuracy:false})
.then(function(position){
self.lat = position.coords.latitude;
self.lon = position.coords.longitude;
console.log('latlong = '+self.lat+','+self.lon);
var params = {
callback: 'angular.callbacks._0',
page: self.page,
ll: self.lat+','+self.lon,
term: self.term,
oauth_consumer_key: self.oauthConKey, //Consumer Key
oauth_token: self.oauthToken, //Token
oauth_signature_method: self.oauthSigMeth,
oauth_timestamp: self.timeStamp,
//new Date().getTime(),
oauth_nonce: self.ranStr
};
var signature = oauthSignature.generate(method, url, params, consumerSecret, tokenSecret, { encodeSignature: false});
params['oauth_signature'] = signature;
console.log('url ='+url);
console.log('params.ll = '+params.ll);
$http.jsonp(url, {params: params}).success(function (callback) {
self.isLoading = false;
console.log(callback.businesses);
if (callback.businesses.length == 0) {
self.hasMore = false;
} else {
angular.forEach(callback.businesses, function (business) {
self.results.push(business);
});
}
self.isLoading = false;
deferred.resolve(callback.businesses);
})
.error( function (callback, status, headers, config) {
self.isLoading = false;
console.error('data not received');
console.error('data: '+callback);
console.error('status: '+status);
console.error('headers: '+headers);
console.error('congig: '+config);
deferred.reject(callback);
});
}, function(err) {
console.error('Error getting position');
console.error(err);
$ionicPopup.alert({
'title': 'Please turn on geolocation',
'template': 'It looks like you have geolocation turned off. Please turn on geolocation in your app settings to use this app.'
});
})
});
return deferred.promise;
}
};
self.load();
return self;
});
I tested my app in the iOS emulator and noticed that the gps does not work.
In the emulator I set the location to "Apple"
and installed the corodova plugin by: "cordova plugin add org.apache.cordova.geolocation".
Here is my Code:
angular.module('home', ['services'])
.controller('homeCtrl',
function ($scope, $location, $state, serverAPI, $ionicPopup) {
$scope.buttonType = "icon ion-search";
$scope.buttonDisable = false;
$scope.text = 'Search';
var UID = JSON.parse(window.localStorage.getItem('Credentials')).UID;
serverAPI.getUserData(UID, function (data) {
$scope.userName = data.userName;
$scope.points = data.points;
$scope.fotoId = data.fotoId;
console.log(data);
});
$scope.click = function () {
$scope.buttonDisable = true;
$scope.text = 'Searching';
$scope.buttonType = 'icon ion-loading-a';
// //Grap geoLocation
var location = navigator.geolocation.getCurrentPosition(saveGeoData, onError);
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
};
var saveGeoData = function (geoData) {
console.log("nach geo");
var myPosition = {
'longitude': geoData.coords.longitude,
'latitude': geoData.coords.latitude
};
console.log("ss");
console.log(myPosition.latitude);
window.localStorage.setItem('myPosition', JSON.stringify(myPosition));
//If geoloaction is saved successfully => Send geodata to server to receive teammate
sendToServer(myPosition);
}
//Send current location to Server to receive teammate
var sendToServer = function (myPosition) {
serverAPI.searchPartnerToPlayWith(myPosition.longitude, myPosition.latitude, UID, function (data) {
//No other players around you. Server returns -1
if (data == -1) {
$ionicPopup.alert({
title: 'Too bad :(',
template: 'Unfortunateley there are no other players around you. Try it some other time!'
});
} else {
window.localStorage.setItem('teammate', data.username);
window.localStorage.setItem('isEnummeration', data.taskType);
window.localStorage.setItem('task', data.task);
var teammatePosition = {
'longitude': data.longitude,
'latitude': data.latitude
};
window.localStorage.setItem('teammatePosition', teammatePosition);
//TODO: data.fotoId => request foto from server
$state.go('tab.play-screen');
}
})
}
};
})
When the function click is called, it just stops in Line:
var location = navigator.geolocation.getCurrentPosition(saveGeoData, onError);
Do you have a guess whats my problem? In the browser it works just fine.
Thanks!
Make sure you include this file into your project.
https://github.com/apache/cordova-plugin-geolocation/blob/master/www/geolocation.js
It can be high probability cause from there, this function not exist in your project, getCurrentPosition.