I am angularjs newbie. I try to use ionic framework to do a practice, so that will use angularjs. And I got a little problem. I want to before insert data to check this data have exist, if not exist that will insert a new data.
On this method getContent.then(function(res){}), I will check this return res.length, if equal 0 I want insert this data. When I run, that will execute this console, and obj is have data. But at finally, I want get all data, but the data is empty.
But I found If I remove this insert method outside getContent.then(function(res){}), it's work. I have no idea how to fix this problem and cause this reason.
Thanks your help.
This is my Controller code
angular.module('starter.controllers', ['sqlite.services'])
.controller('TestCtrl', function($scope, $http, Tests, SQLService) {
SQLService.setup();
var new_tests = new Array();
$http.get('https://XXXXX').then(function(response){
var datas = response.data;
for (data_ in datas) {
var obj = {
id: datas[data_].content_id,
title: datas[data_].title,
url: datas[data_].url,
content: datas[data_].content
};
var getContent = SQLService.get_one(obj.id);
getContent.then(function(res) {
console.log('res ' , res);
console.log('res ' , res.length); // length get 0
if(res.length == 0) {
console.log('insert obj ' , obj);
console.log('SQLService ' , SQLService);
SQLService.insert(obj);
}
else if (res.length == 1) {
console.log('edit obj ' , obj);
}
});
// SQLService.insert(obj); // If I write insert code here is work for me
new_tests.push(obj);
}
})
.finally(function() {
SQLService.all().then(function (results) {
$scope.tests = results;
console.log('results ' , results);
});
});
This is my sql_service.js
angular.module('sqlite.services', [])
.factory('SQLService', function($q) {
var db;
function createDB() {
try {
if (window.cordova) {
$cordovaSQLite.deleteDB("my.db");
db = $cordovaSQLite.openDB({name: 'my.db'}); // device
}
else{
db = window.openDatabase("my.db", '1', 'my', 1024 * 1024 * 100); // browser
}
db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS pixnet (id integer not null primary key autoincrement, content_id text, title text, url, text, content text)", []);
});
}
catch(err) {
console.log('Error processing SQL: ' + err);
}
console.log('database created');
}
function insertNewContent(newContent) {
console.log('--insert--');
return promisedQuery("INSERT INTO pixnet (content_id, title, url, content) VALUES ('" + newContent.id + "', '" + newContent.title + "', '" + newContent.url + "', '" + newContent.content + "')", defaultResultHandler, defaultErrorHandler);
}
function getContents() {
return promisedQuery("SELECT * FROM pixnet", defaultResultHandler, defaultErrorHandler);
}
function updateContent(content){
console.log('update content ' , content);
return promisedQuery("UPDATE pixnet SET title='" + content.title + "', content='" + content.content + "' WHERE content_id = '" + content.id + "'", defaultResultHandler, defaultErrorHandler);
}
function getContent(content_id) {
return promisedQuery("SELECT * FROM pixnet WHERE content_id = '" + content_id + "'", defaultResultHandler, defaultErrorHandler);
}
function defaultResultHandler(deferred) {
return function(tx, results) {
console.log('defaultResultHandler results ' , results);
var len = results.rows.length;
var output_results = [];
for (var i=0; i<len; i++){
var t = {
'id': results.rows.item(i).id,
'content_id': results.rows.item(i).content_id,
'title': results.rows.item(i).title,
'url': results.rows.item(i).url,
'content': results.rows.item(i).content
};
output_results.push(t);
}
deferred.resolve(output_results);
}
}
function defaultErrorHandler(deferred) {
return function(tx, results) {
var len = 0;
var output_results = '';
deferred.resolve(output_results);
}
}
function promisedQuery(query, successCB, errorCB) {
var deferred = $q.defer();
db.transaction(function(tx){
tx.executeSql(query, [], successCB(deferred), errorCB(deferred));
}, errorCB);
return deferred.promise;
}
return {
setup: function() {
return createDB();
},
insert: function(content) {
return insertNewContent(content);
},
edit: function(content) {
return updateContent(content);
},
get_one: function(content_id) {
return getContent(content_id);
},
all: function() {
return getContents();
}
}
});
I believe what's happening is that the 'deferred' you create in promiseQuery is never resolved:
function promisedQuery(query, successCB, errorCB) {
var deferred = $q.defer();
db.transaction(function(tx){
tx.executeSql(query, [], successCB(deferred), errorCB(deferred));
}, errorCB);
return deferred.promise;
}
Since you are using cordova sqlite plugin, looking at the source code we see the third argument of the 'transaction' function is the success callback.
https://github.com/brodysoft/Cordova-SQLitePlugin/blob/master/www/SQLitePlugin.js#L74
So this means you want to resolve your promise in either of those callbacks. Try the following:
function promisedQuery(query, successCB, errorCB) {
var deferred = $q.defer();
db.transaction(function(tx){
tx.executeSql(query, [], successCB(deferred), errorCB(deferred));
}, errorCB, deferred.resolve);
return deferred.promise;
}
Passing the deferred.resolve function into the success callback (the last argument of transaction) will get it called when the transaction finishes.
angular.module('starter.controllers', ['sqlite.services'])
.controller('TestCtrl', function($scope, $http, Tests, SQLService) {
SQLService.setup();
var new_tests = new Array();
var call_async_in_loop = function(obj) {
var getContent = SQLService.get_one(obj.id);
getContent.then(function(res) {
console.log('res ', res);
console.log('res ', res.length); // length get 0
if (res.length == 0) {
console.log('insert obj ', obj);
console.log('SQLService ', SQLService);
SQLService.insert(obj);
} else if (res.length == 1) {
console.log('edit obj ', obj);
}
});
}
$http.get('https://XXXXX').then(function(response) {
var datas = response.data;
for (data_ in datas) {
var obj = {
id: datas[data_].content_id,
title: datas[data_].title,
url: datas[data_].url,
content: datas[data_].content
};
call_async_in_loop(obj)
new_tests.push(obj);
}
})
.finally(function() {
SQLService.all().then(function(results) {
$scope.tests = results;
console.log('results ', results);
});
});
You loosing the reference to obj because of the async call SQLService.get_one(obj.id). When the promise is resolved the for loop is already finished. So u have to create a closure to keep reference to obj.
Related
I have the below JavaScript code to develop an app in Fuse Tools. There is one last error that I cannot seem to understand and that is that my variable b64data should be a global variable and is not updating it's value from the capturePhoto function and letting me send the updated value in the submitPhoto function to the server. It should send the base64 encoded value as the picture variable in my POST function. Any help is appreciated!
var Observable = require("FuseJS/Observable");
let ImageTools = require("FuseJS/ImageTools");
var FileSystem = require("FuseJS/FileSystem");
var Base64 = require("FuseJS/Base64");
var Camera = _camera;
var b64data;
var captureMode = Observable();
var flashMode = Observable();
function getCameraInfo() {
Camera.getCameraInfo()
.then(function(info) {
console.log("captureMode: " + info[Camera.INFO_CAPTURE_MODE]);
console.log("flashMode: " + info[Camera.INFO_FLASH_MODE]);
console.log("cameraFacing: " + info[Camera.INFO_CAMERA_FACING]);
console.log("supportedFlashModes: " + info[Camera.INFO_SUPPORTED_FLASH_MODES].join());
captureMode.value = info[Camera.INFO_CAPTURE_MODE];
flashMode.value = info[Camera.INFO_FLASH_MODE];
if (Camera.INFO_PHOTO_RESOLUTIONS in info) {
var availableResolutions = info[Camera.INFO_PHOTO_RESOLUTIONS];
availableResolutions.forEach(function(e) {
console.log(e.width + "x" + e.height);
});
photoResolution = availableResolutions[Math.floor(availableResolutions.length * 0.4)];
var options = {};
options[Camera.OPTION_PHOTO_RESOLUTION] = photoResolution;
Camera.setPhotoOptions(options)
.then(function() {
console.log("New photo options set: " + JSON.stringify(options));
})
.catch(function(error) {
console.log("Failed to set photo options: " + error);
});
}
})
.catch(function(err) {
console.log("Failed to get camera info: " + err);
});
}
getCameraInfo();
function nextFlashMode() {
if (flashMode.value == Camera.FLASH_MODE_AUTO) return Camera.FLASH_MODE_ON;
else if (flashMode.value == Camera.FLASH_MODE_ON) return Camera.FLASH_MODE_OFF;
else if (flashMode.value == Camera.FLASH_MODE_OFF) return Camera.FLASH_MODE_AUTO;
else throw "Invalid flash mode";
}
function setCaptureMode(cm) {
Camera.setCaptureMode(cm)
.then(function(mode) {
captureMode.value = mode;
console.log("Capture mode set to: " + mode);
})
.catch(function(err) {
console.log("Failed to set capture mode: " + err);
});
}
function capturePhoto() {
Camera.capturePhoto()
.then(function (photo) {
photo.save()
.then(function(filePath) {
console.log("Photo saved to: " + filePath);
var arrayBuff = FileSystem.readBufferFromFileSync(filePath);
var b64data = Base64.encodeBuffer(arrayBuff); // send this to the backend
photo.release();
})
.catch(function(error) {
console.log("Failed to save photo: " + error);
photo.release();
});
})
.catch(function (error) {
console.log("Failed to capture photo: " + error);
});
}
var isRecording = Observable(false);
var recordingSession = null;
function startRecording() {
isRecording.value = true;
Camera.startRecording()
.then(function (session) {
recordingSession = session;
})
.catch(function (error) {
console.log("Failed to start recording: " + error);
isRecording.value = false;
});
}
function stopRecording() {
isRecording.value = false;
recordingSession.stop()
.then(function (recording) {
router.push("VideoPage", recording.filePath());
})
.catch(function (error) {
console.log("Failed to stop recording: " + error);
});
recordingSession = null;
}
var cameraBack = true;
function flipCameraFacing() {
var front = Camera.CAMERA_FACING_FRONT;
var back = Camera.CAMERA_FACING_BACK;
Camera.setCameraFacing(cameraBack ? front : back)
.then(function (newFacing) {
cameraBack = newFacing == back;
getCameraInfo();
console.log("Camera facing set to: " + (newFacing == back ? "back" : "front"));
})
.catch(function (err) {
console.log("Failed to set camera facing: " + err);
});
}
function changeFlashMode() {
Camera.setFlashMode(nextFlashMode())
.then(function(newFlashMode) {
flashMode.value = newFlashMode;
console.log("Flash mode set to: " + flashMode.value);
})
.catch(function(err) {
console.log("Failed to set flash mode: " + err);
});
}
var name = Observable();
var email = Observable();
var market = Observable();
module.exports = {
name: name,
email: email,
market: market,
b64data: b64data,
submitPhoto: submitPhoto,
captureMode: captureMode,
setCaptureModePhoto: function () { setCaptureMode(Camera.CAPTURE_MODE_PHOTO); },
setCaptureModeVideo: function () { setCaptureMode(Camera.CAPTURE_MODE_VIDEO); },
capturePhoto: capturePhoto,
startRecording: startRecording,
stopRecording: stopRecording,
isRecording: isRecording,
flipCameraFacing: flipCameraFacing,
flashMode: flashMode,
changeFlashMode: changeFlashMode,
}
function submitPhoto(){
console.log("name: "+name);
console.log("email: "+email);
console.log("market: "+market);
fetch('http://fanbeauties.com/app/submit-photo.php?pass=MY_PASS', {
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: '&name='+name+'&email='+email+'&market='+market+'&picture='+b64data
});
};
May be because of you are declaring b64data again in capturePhoto function on line 72 in your shared code.
try
b64data = ...
instead of
var b64data = ...
i'm developing an app that received from a server a JSON array and divided data in a specific way, i've a portion of code that works if i use it alone but if i tried to insert it in an application it doesn't work.
This is my code:
ionicApp.controller('DefaultController', DefaultController)
.factory('dataService', dataService);
DefaultController.$inject = ['dataService', '$http'];
function DefaultController(dataService, $http) {
var vm = this;
console.log("Dentro ctrl");
getEvents();
function getEvents() {
console.log("Dentro getEvents");
return dataService.getEvents()
.then(function (data) {
console.log("data: " + data);
vm.data = data;
console.log("vm.data: " + vm.data);
return vm.data;
});
}
vm.submit = function (){
console.log("funzione");
console.log(vm.form);
var data = vm.form; // IMPORTANT
//console.clear();
var link = 'http://localhost/<path>/api/apiDoFix.php';
var mail = window.localStorage.getItem("mail");
var scelta = window.localStorage.getItem("scelta");
console.log(data);
console.log ("EMAIL" + mail);
console.log ("SCELTA" + scelta);
$http.post(link, {giorno: data.giorno, ora: data.ora, mail: mail, scelta: scelta})
.then(function (res){
console.log("Dentro http.post");
var response = res.data;
if (response != 'F'){
console.log("Dentro if");
console.log(response);
//window.location.href ="/#/main";
} else {
console.log("Dentro else");
}
});
};
}
dataService.$inject = ['$http'];
function dataService($http) {
console.log("qua");
var service = {
getEvents: getEvents
};
return service;
function getEvents() {
console.log("qua2");
var config = {
transformResponse: function (data, headers) {
var result = {
events: [],
schedules: []
};
var events = JSON.parse(data);
var dates = [];
console.log("qua3");
for (var i = 0; i < events.length; i++) {
if (dates.indexOf(events[i].day) === -1) {
var date = events[i].day;
dates.push(date);
result.events.push({
date: date
});
}
result.schedules.push({
date: events[i].day,
time: events[i].time
});
}
console.log("result: " + result);
return result;
}
};
return $http.get('http://localhost/ShuttleFIX/api/apiTimes.php', config)
.then(getEventsCompleted)
.catch(getEventsFailed);
function getEventsCompleted(response) {
console.log("response " + response.data);
return response.data;
}
function getEventsFailed(error) {
console.error(error);
}
}
}
is it possible to rewrite this code in a controller function without using factory?
Thank's
I want to get the image path after the execution of the uploadFiles function. This way, I will have the value assigned to self.ProjectImagePath. But it is not working, I think it executes right after the function call. Anyone can help ?
self.submitProject = function(file) {
console.log("Submit Project \n");
uploadFiles.apply(this, arguments);
console.log(self.ProjectImagePath); ///ERROR HERE!!!! (UNDEFINED)
var data = JSON.stringify({
name: self.ProjectName,
room: self.room,
managers: self.Managers,
members: self.ProjectMembers,
image: self.ProjectImagePath
});
//console.log(data);
$http.post('/rooms/' + self.room + '/project', data).success(function(data) {
//$window.location.href = "/";
});
}
function uploadFiles(file) {
file.upload = Upload.upload({
url: 'projectImages/upload',
data: {
file: file
}
});
file.upload.then(function(response) {
$timeout(function() {
file.result = response.data;
self.ProjectImagePath = file.result;
});
}, function(response) {
if (response.status > 0)
self.errorMsg = response.status + ': ' + response.data;
});
}
After execution, the image is uploaded to the server but I cant get its path.
Im using AngularJS
You were having issues with calling code before the promise (asynchronous action) was finished.
This should do what you need:
self.submitProject = function(file) {
console.log("Submit Project");
function handleSuccess(response) {
self.ProjectImagePath = file.result = response.data;
// Should work correctly.
console.log(self.ProjectImage);
var data = JSON.stringify({
name: self.ProjectName,
room: self.room,
managers: self.Managers,
members: self.ProjectMembers,
image: self.ProjectImagePath
});
$http.post('/rooms/' + self.room + '/project', data).success(function(data) {
//$window.location.href = "/";
});
}
function handleError(response) {
if (response.status > 0)
self.errorMsg = response.status + ': ' + response.data;
}
uploadFiles(file, handleSuccess, handleError);
};
function uploadFiles(file, successCallback, errorCallback) {
file.upload = Upload.upload({
url: 'projectImages/upload',
data: {
file: file
}
});
file.upload.then(successCallback, errorCallback);
}
I am using a javascript bridge to communicate between a hybrid web app and iOS using a webView.
my question is how to get the function ios_getUserID() from within the script to put a value to the variable UserID that exists above the javascript bridge function.
I have a web page and connected to it is a script js file. scripts.js looks like this:
var userID="";
//javascript ios bridge
window.onerror = function(err) {
log('window.onerror: ' + err)
}
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener('WebViewJavascriptBridgeReady', function() {
callback(WebViewJavascriptBridge)
}, false)
}
}
connectWebViewJavascriptBridge(function(bridge) {
var uniqueId = 1
function log(message, data) {
var log = document.getElementById('log')
var el = document.createElement('div')
el.className = 'logLine'
el.innerHTML = uniqueId++ + '. ' + message + ':<br/>' + JSON.stringify(data)
if (log.children.length) { log.insertBefore(el, log.children[0]) }
else { log.appendChild(el) }
}
bridge.init(function(message, responseCallback) {
log('JS got a message', message)
var data = { 'Javascript Responds':'Weeeeeeee!' }
log('JS responding with', data)
responseCallback(data)
})
bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {
log('ObjC called testJavascriptHandler with', data)
var responseData = { 'Javascript Says':'Right back atcha!' }
log('JS responding with', responseData)
responseCallback(responseData)
})
bridge.registerHandler('softUserID', function(data, responseCallback) {
log('softUserID ObjC called testJavascriptHandler with', data)
alert(data.userID);
var responseData = { 'Javascript Says':'super!' }
log('JS responding with', responseData)
responseCallback(responseData)
})
ios_getUserID = function(){
var obj = '{"action" : "getUserID"}';
//alert("crossing bridge");
var data = obj
log('JS sending message', data)
bridge.send(data, function(responseData) {
log('JS got response', responseData)
alert(responseData);
})
}
});
I have some code in node.js using express. I route a call to request data from a mysql database, and what I want to do is pass that to another function to restructure the returned json from a tabular form (table query) to a hierarchy type json.
I've tested the script separately to restructure the output from my sql query. However, I am having trouble passing it from my query function to my new script(function)
I'm just not seeing what I am doing wrong. Any help please and thanks.
exports.get_site_menu = function (req, res) {
var dbc;
console.log('In menu setup');
async.waterfall([
// get a connection
function (callback) {
db.db(callback);
}
,
querylookup, modifyjson
], completed);
function querylookup(dbclient, res) {
dbc = dbclient;
dbc.query("SELECT categories, " +
"subcategories, " +
"pid, " +
"title, " +
"description " +
"FROM MENU_SELECT_ACTIVE_VIEW " +
"where company_id = ? and site_id = ?", [req.query.companyid, req.query.siteid], res);
}
function modifyjson(err, res) {
categories = [];
console.log('results ' + res);
res.forEach(function (entry) {
var cindex = categories.map(function (category) {
return category.name;
}).indexOf(entry.categories);
console.log(cindex);
if (cindex < 0) {
// Not found in categories array
cindex = categories.push({
name: entry.categories,
subcategories: []
}) - 1; // -1 to fix the index
}
// Lets search the subcategory
var category = categories[cindex];
var sindex = category.subcategories.map(
function (subcategory) {
return subcategory.name;
}
).indexOf(entry.subcategories);
if (sindex < 0) {
// Not Found
sindex = category.subcategories.push({
name: entry.subcategories,
items: []
}) - 1;
}
// Subcategory exists. Just push
category.subcategories[sindex].items.push({
pid: entry.pid,
description: entry.description,
title: entry.title
});
});
menu = {
menu: {
categories: categories
}
};
console.log('menu ' + menu);
}
function completed(err, menu, fields) {
if (dbc) dbc.end();
if (err) {
callback(err);
} else {
console.log(menu);
res.contentType('json');
res.send(JSON.stringify(menu));
}
}
};
You need to pass each result to own callback to pass next function. I have refactored your code like;
exports.get_site_menu = function (req, res) {
var dbc;
console.log('In menu setup');
async.waterfall([
// get a connection
function (callback) {
db.db(callback, some_result);
},
function querylookup(dbclient, res, callback) {
dbc = dbclient;
dbc.query("SELECT categories, " +
"subcategories, " +
"pid, " +
"title, " +
"description " +
"FROM MENU_SELECT_ACTIVE_VIEW " +
"where company_id = ? and site_id = ?", [req.query.companyid, req.query.siteid], res);
callback(null, result_from_queryLookup);
},
function modifyjson(err, res, callback) {
categories = [];
console.log('results ' + res);
res.forEach(function (entry) {
var cindex = categories.map(function (category) {
return category.name;
}).indexOf(entry.categories);
console.log(cindex);
if (cindex < 0) {
// Not found in categories array
cindex = categories.push({
name: entry.categories,
subcategories: []
}) - 1; // -1 to fix the index
}
// Lets search the subcategory
var category = categories[cindex];
var sindex = category.subcategories.map(
function (subcategory) {
return subcategory.name;
}
).indexOf(entry.subcategories);
if (sindex < 0) {
// Not Found
sindex = category.subcategories.push({
name: entry.subcategories,
items: []
}) - 1;
}
// Subcategory exists. Just push
category.subcategories[sindex].items.push({
pid: entry.pid,
description: entry.description,
title: entry.title
});
});
menu = {
menu: {
categories: categories
}
};
console.log('menu ' + menu);
callback(null, menu, fields);
}
], function completed(err, menu, fields) {
if (dbc) dbc.end();
if (err) {
callback(err);
} else {
console.log(menu);
res.contentType('json');
res.send(JSON.stringify(menu));
}
});
};
Especially, be careful on callback parts.