I am trying to use a service
that runs an asynchronous function.
I am trying to call the factory, then do something only it is resolved.
But it doesn't work, I get the error : Uncaught TypeError: Cannot read property 'then' of undefined
I am declaring the deferred object into the service function and I return its promise.
Can you help me please ?
app.js:
angular.module('SnowBoard', ['ionic', 'ngCookies', 'ui.unique', 'SnowBoard.controllers', 'SnowBoard.services'])
.run(["isPhoneGap","connectionStatus", 'updateProDB', "$ionicPlatform", '$q', 'sessionService', 'imagesService', function(isPhoneGap, connectionStatus, updateProDB, $ionicPlatform, $q, sessionService, imagesService) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
var promise = updateProDB.get();
promise.then(
function(data) {
imagesService.checkIfImagesExistAllAtOnce(prodata);
},
function(error) {
});
}])
service.js:
.service('updateProDB', ['isPhoneGap', 'connectionStatus', 'isIOS', '$q', 'sessionService', function updateProDBFactory(isPhoneGap, connectionStatus, isIOS, $q, sessionService) {
this.get = function(){
var debugOptionUseLocalDB=0;
var prodata=[];
var gotANewDB;
var dbReadyDeferred = $q.defer();
if (typeof debugOptionUseLocalDB != 'undefined' && debugOptionUseLocalDB) {
fallbackToLocalDBfile();
return dbReadyDeferred.promise;
gotANewDB = 1;
console.log('on a fini fallbackToLocalDBfile, et dbReadyDeferred.state()='+dbReadyDeferred.state());
}else{
if(connectionStatus == 'online'){
console.log("reaching DB on server (getJsonpFile)...");
getDBfileXHR(dbUrl()).then(function(){ //if resolved
console.log(prodata);
return dbReadyDeferred.promise;
}, function (){ // if rejected
console.log("...basic XHR request failed, falling back to local DB file...and sending mail to dev.");
fallbackToLocalDBfile();
return dbReadyDeferred.promise;
var body = "";
if ( isPhoneGap ) {
body += " Platform : phonegap";
body += " device.cordova : "+device.cordova;
body += " device.model : "+device.model;
body += " device.name : "+device.name;
body += " device.platform : "+device.platform;
body += " device.uuid : "+device.uuid;
body += " device.version : "+device.version;
} else {
body += "Platform : not phonegap -> web browser"
body += "navigator.userAgent : "+navigator.userAgent;
}
var data={
userEmail: "louisromain@yahoo.fr",
subject: "BoardLine dev issue: had to fallback to local DB file",
destEmail: "louisromain@yahoo.fr",
body: body
}
sendToServer(data).done(funcSuccess).fail(funcError);
function funcSuccess(data /* , textStatus, jqXHR */ ) {
console.log("Message to dev successfully sent");
}
function funcError(data , textStatus, jqXHR ) {
console.log("The message to dev could not be sent...");
}
});
}else{ //offline
console.log('device is offline');
if(localStorage) {
if ( isPhoneGap || !isIOS() ) { //BUG iOS safari doesn't work with this (Cf. Philippe's ipad)
if (localStorage.getItem("proDB") === null ) { //if proDB exists in localStorage
fallbackToLocalDBfile();
} else {
//popShortToast("...reading DB in localStorage.");
var data = JSON.parse(localStorage["proDB"]); //read current localstorage
prodata = storeJsonInProdata(data);
sessionService.store('prodata', prodata);
dbReadyDeferred.resolve(); //initializeSelectButtons();
return dbReadyDeferred.promise;
}
}
}else{ //if localStorage not available, read local file
prodata = fallbackToLocalDBfile();
return dbReadyDeferred.promise;
}
}
}
function getDBfileXHR(url) {
var getDBfileXHRdeferred = $q.defer();
var request = new XMLHttpRequest();
request.open("GET", url, true); //3rd parameter is sync/async
request.timeout = 2000;
//console.log(url);
request.onreadystatechange = function() { //Call a function when the state changes.
if (request.readyState == 4) {
if (request.status == 200 || request.status == 0) {
console.log('we get a response from XHR');
//popShortToast("...updating DB from server using simple XHR.");
var jsonText = request.responseText.replace("callback(", "").replace(");", "");
prodata = storeJsonInProdata(JSON.parse(jsonText));
sessionService.store('prodata', prodata);
// console.log(prodata);
gotANewDB = 1;
getDBfileXHRdeferred.resolve();
dbReadyDeferred.resolve();
} else {
console.log('error : request.status = '+request.status);
getDBfileXHRdeferred.reject();
}
}
}
console.log("Sending XMLHttpRequest...");
request.send();
return getDBfileXHRdeferred.promise;
}
function dbUrl(){
return unescape(encodeURIComponent("http://user:pass@boardlineapp.com/app/proDB.jsonp")); //JSONP
}
function fallbackToLocalDBfile(){
getDBfileXHR('proDB.jsonp').then(function(){ //if resolved
console.log(prodata);
return dbReadyDeferred.promise;
});
}
}
function sendToServer(dataToSend) {
return $.ajax({
url: 'http://aurel:aurel40@boardlineapp.com/app/mail.php',
type: "POST",
dataType: "xml",
data: dataToSend
});
}
function storeJsonInProdata(data) { //function to store the DB json file into a variable prodata usable in the whole app
console.log("storing json in prodata");
//clear prodata first
var prodata=[];
//if JSON
var lines=[];
for(var i = 0; i <= data.length; i++){
lines[i]=data[i];
}
var fieldnames=lines[0];
//if tab separated TXT with each model on a separate line
// var lines=data.split(/\n/);
// var fieldnames=lines[0].split(/\t/);
var i;
prodata.push(lines[0]);
//prodata.push(0);
for (i = 1; i < lines.length-1; ++i) {
//if JSON
var fields=lines[i];
//if TXT
// var fields=lines[i].split(/\t/);
//prodata.push(i);
var j;
prodata[i]={};
prodata[i]['id']=i; //auto id, there is no more 'id' column in the DB file.
for (j = 0; j < fields.length; ++j) {
var str=fieldnames[j];
prodata[i][str]=fields[j];
}
}
return prodata;
}
}]);