So my readingController calls getRomanization in the main body the first time and it in turn calls the Romanize factory service (shown below controller). This all works fine the fist time but the second time when round when getRomanization is called at the end of checkRomanization the Romanize service comes up as undefined in Chrome. What happens to the Romanize service? why does it only run successfully once?
Please help me with this as I have been stuck for ages.
var readingController = function ($scope, Romanize){
$scope.getRomanization = function(Romanize){
$scope.currentMaterial = $scope.sections[$scope.sectionNumber].tutorials[$scope.tutorialNumber].material[$scope.questionNumber];
Romanize.get($scope.currentMaterial).then(function(d){
$scope.romanized = d;
});
$scope.$apply();
};
$scope.getRomanization(Romanize);
$scope.$apply();
$scope.checkRomanization = function(userRomanization){
if ($scope.romanized === userRomanization){
$scope.questionNumber++;
$scope.getRomanization();
};
}
}
app.factory('Romanize', ['$http', 'Position', function($http, Position){
return{
get: function(query){
var url= Position.sections[Position.sectionNumber].romanizeService + "?korean=" + query;
var promise = $http.get(url).then(function(d) {
var parts = $(d.data).find("span");
var array = [];
for (var x = 0; x<parts.length; x++){
array.push(parts[x].title);
}
var result = array.join("");
return result;
});
return promise;
}
};
}]);
Your second call to getRomanize is missing the service name as an argument
$scope.checkRomanization = function(userRomanization){
if ($scope.romanized === userRomanization){
$scope.questionNumber++;
$scope.getRomanization(Romanize);
};
};
Related
I have created the service below.
app.factory('userProfileFactory', ['FBDB', 'searchParam', function(FBDB, searchParam) {
var personalKey;
return {
userProfile: function(searchEmail) {
var deferred = $q.defer();
var FBref = new Firebase(FBDB).child('items');
var promise = FBref.orderByChild('email')
.startAt(searchEmail)
.endAt(searchEmail)
.on('value', function(snapshot) {
var data = snapshot.val();
personalKey = Object.keys(data)[0];
deferred.resolve(personalKey);
});
return deferred.promise;
}
};
}]);
My Controller is as below. The issue is that it takes a moment for results to be returned. So when the $save function is called outside factory function, it reports an 'undefined variable'. How can I make it work when $save is outside?
app.controller('profileCtrl', ['userProfileFactory', 'FBDB', '$firebaseArray', function(userProfileFactory, FBDB, $firebaseArray) {
var FBref = new Firebase(FBDB).child('items');
userProfileFactory.userProfile().then(function(res){
var personalKey = res;
item.personalKey = res;
//$firebaseArray(FBref)$save(item); It works here. But moved this from here...
})
$firebaseArray(FBref)$save(item); //...to here. It does not work.
}]);
In your code, the line:
$firebaseArray(FBref)$save(item);
will execute before the resolve function:
function(res){
var personalKey = res;
item.personalKey = res;
}
The resolve function waits for the userProfileFactory.userProfile() promise to resolve (data to be returned) before executing, whereas the firebase.save line does not. You need to put it back inside of the then(resolve) function.
This is module and controller code
var app = angular.module('apApp',[]);
app.controller('apCtrl', ['$scope','$http','getPopByBranch',function($scope, $http,getPopByBranch)
{
$scope.greeting = 'Hola!';
console.log(getPopByBranch.test) ;
}]);
var boot_apApp = document.getElementById('apApp');
angular.element(document).ready(function() {
angular.bootstrap(boot_apApp, ['apApp']);
});
This is my service code saved in separate js file
angular.module('apApp').factory('getPopByBranch', function($http){
var pops = {};
pops.test = function(){ return "Hello";};
//i want value of second function also
//pops.test = function foo(){ return "Bye";};
return pops;
});
output in console
function(){ return "Hello";}
The problem is that i want only hello or some value returned .
You need to call the function. Update from
console.log(getPopByBranch.test);
to
console.log(getPopByBranch.test());
My app had this .run
.run(function ($rootScope, $http) {
$rootScope.server = "http://127.0.0.1:5000/rawDemo";
var call = $rootScope.server + "/frontEnd/GetStructure";
var texts = {};
texts.languages = {};
$http.get(call).then(function (response) {
for (var i = 0; i < response.data.languages.length; i++) {
texts.languages[response.data.languages[i].iso2] = {
'title': response.data.languages[i].title,
'description': response.data.languages[i].description,
'keywords': response.data.languages[i].keywords,
'frontEndTexts': response.data.languages[i].frontEndTexts
};
}
$rootScope.texts = texts;
$rootScope.webshop = response.data;
$rootScope.webshop.language = response.data.culture.language;
$rootScope.webshop.numberFormat = "";
$rootScope.carouselData = response.data.frontEndConfig.customConfiguration.mjCarousel;
console.log('end run');
});
})
.And some of my resolvers perform a call in a service...
angular
.module('app')
.factory('Products',['$http', '$rootScope', function($http, $rootScope){
return {
listByCategories : function (categories){
console.log('begin service');
var call = $rootScope.server + '/products/list/categories/' + categories.fullPath +'?page1&recordsPerPage=2' ;
return $http.get(call).then(function(response) {
return response.data;
});
}
}
}])
My expected result in console.log supposed to be:
- end run
- begin service
but instead..begin service starts before the end run. It's because the .run finish and keep the $http executing asynchronously and go on to the next stages like resolvers, for example.
According to my research on this website, it's impossible to make the $http works synchronous. So, my question is...any hint about how to handle the scenario ? My service depends from data that's must be loaded before anything.
I cannot "merge" the .run and the service because all the others views, services, must have the .run executed before. in my .run I load dozen of global configurations basically.
UPDATE : I'm still stucked...but I'm trying something...I changed the way I'm doing the things..
so, on my .run
$rootScope.loadWebshop = function(callBack) {
if($rootScope.loaded) { return ; }
var call = $rootScope.server + "/frontEnd/GetStructure";
var texts = {};
texts.languages = {};
$http.get(call).then(function (response) {
for (var i = 0; i < response.data.languages.length; i++) {
texts.languages[response.data.languages[i].iso2] = {
'title': response.data.languages[i].title,
'description': response.data.languages[i].description,
'keywords': response.data.languages[i].keywords,
'frontEndTexts': response.data.languages[i].frontEndTexts
};
}
$rootScope.texts = texts;
$rootScope.webshop = response.data;
$rootScope.webshop.language = response.data.culture.language;
$rootScope.webshop.numberFormat = "";
$rootScope.carouselData = response.data.frontEndConfig.customConfiguration.mjCarousel;
$rootScope.loaded = true;
console.log('end .run');
callBack();
});
}
..And on my service :
listByCategories : function (categories){
return $rootScope.loadWebshop (function () {
console.log('begin service');
var call = $rootScope.server + '/products/list/categories/' + categories.fullPath +'?page1&recordsPerPage=2' ;
return $http.get(call).then(function(response) {
return response.data;
});
});
}
Now I'm facing a different issue...it's returns undefined because it's asyncronous, even using premise. Any clue ??
I have a problem when calling a service created using .factory in my controller.
The code looks like the following.
Factory (app.js):
.factory('Database',function($http){
return {
getDatabase: function(){
var database = {};
$http.get('http://localhost:3001/lookup').
success(function(data){
database.companyInfo = data.info.companyInfo;
});
}).
error(function(data){
console.log('Error' + data);
});
return database;
}
};
})
Controller:
angular.module('webClientApp')
.controller('MainCtrl', function (Database,Features,$scope,$http) {
$scope.databaseString = [];
$scope.quarters = ['Q1','Q2','Q3','Q4'];
$scope.years = ['2004','2005','2006','2007','2008','2009','2010',
'2011','2012','2013','2014'];
$scope.features = Features.getFeatures();
$scope.database = Database.getDatabase();
console.log($scope.database);
Now when I inspect the element in Firebug I get the console.log($scope.database) printed out before the GET statement result. $scope.database is shown as an Object {} with all the proprieties in place.
However if I try to use console.log($scope.database.companyInfo) I get an undefined as result, while instead I should get that data.info.companyInfo' that I passed from theDatabase` service (in this case an array).
What is the problem here? Can someone help me?
(If you need clarifications please let me know..)
The $http.get() call is asynchronous and makes use of promise objects. So, based on the code you provided it seems most likely that you are outputting the $scope.database before the success method is run in the service.
I build all my service methods to pass in a success or failure function. This would be the service:
.factory('Database',function($http){
return {
getDatabase: function(onSuccuess,onFailure){
var database = {};
$http.get('http://localhost:3001/lookup').
success(onSuccess).
error(onFailure);
}
};
})
This would be the controller code:
angular.module('webClientApp')
.controller('MainCtrl', function (Database,Features,$scope,$http) {
$scope.databaseString = [];
$scope.quarters = ['Q1','Q2','Q3','Q4'];
$scope.years = ['2004','2005','2006','2007','2008','2009','2010',
'2011','2012','2013','2014'];
$scope.features = Features.getFeatures();
Database.getDatabase(successFunction,failureFunction);
successFunction = function(data){
$scope.database = data.info.companyInfo;
console.log($scope.database);
});
failureFunction = function(data){
console.log('Error' + data);
}
Change your code in the following way:
.factory('Database',function($http){
return {
getDatabase: function(){
return $http.get('http://localhost:3001/lookup');
}
};
})
Then get the response in controller(Promise chain)
Database.getDatabase()
.then(function(data){
//assign value
})
.catch(function(){
})
The service is returning data (the raw $http response) rather than result (the processed version I want to pass back to my controller), why is the code inside promise being ignored?
///in controller
Romanize.get($scope.currentMaterial).then(function(d){
$scope.romanized = d;
});
//service
app.factory('Romanize', ['$http', 'Position', function($http, Position){
return{
get: function(query){
var url= Position.sections[Position.sectionNumber].romanizeService + "?korean=" + query;
var promise = $http.get(url).success(function(data) {
var parts = $(data).find("span");
var array = [];
for (var x = 0; x<parts.length; x++){
array.push(parts[x].title);
}
var result = array.join("");
return result;
});
return promise;
}
};
}]);
success handler does not provide chain. You should use then:
var promise = $http.get(url).then(function(data) {
var parts = $(data).find("span");
// ...
return result;
});