I'm trying to call a function elsewhere in the same service in AngularJS.
The function I'm calling in my controller is : geocoding, for the moment, all is ok.
But in my geocoding function, I'm calling another function : geovalue.
For now, the script say "geovalue is undefined".
Example of my code
app.service('geo', function(){
this.geovalue = function(val, decimals){
// some code & return a value at the end
};
this.geocoding = function(place, cb) {
// some code
my var = geovalue(val, decimals);
// some code & return a valeu at the end
};
});
geovalue function is also this' method:
my var = this.geovalue(val, decimals);
And seems like it should be:
my var = this.geovalue(place, cb);
Related
I am trying to call factory function in service.
My factory looks like this:
function LMSAppFactory($http) {
var ajaxRequest = 'processRequest.jsp?';
return {
getTableData: getTableData,
};
function getTableData(params, callback) {
alert(1);
$http.get(ajaxRequest + 'requestType=getRecords'+params+'&value=10').then(function (response) {
callback(response.data[1].LMSRecords, response.data[0].LMSRecordsCount);
});
}
}
My service
$scope.branchSearch = function (code){
alert(code);
getData: LMSAppFactory.getTableData;
}
I am getting value in branchSearch function but not call in factory function.
Please suggest where is my mistake?
the code is incomplete but i don't get what you're trying to do in the below code (invocation? assignment? are you trying to define a label statement but why?)
$scope.branchSearch = function (code){
alert(code);
getData: LMSAppFactory.getTableData; // <-- HERE
}
if you want to invoke getTableData a valid invocation could be
$scope.branchSearch = function (code){
alert(code);
var params = {} //pass the parameters here
LMSAppFactory.getTableData(params, function(val1, val2){
//callback behaviour here
})
}
You factory declaration seems to be right, but there is a problem with its call., here getData: LMSAppFactory.getTableData;, you not calling the factory.
Also, you need to inject LMSAppFactory factory inside your service if not already. Like :
angular.module('yourmodule')
.service('yourBranchService', ['LMSAppFactory', function(LMSAppFactory) {
//service code
}
]);
Then, finally in service, make call to factory method :
$scope.branchSearch = function (code){
alert(code);
var inputParams = {}; // fill params
LMSAppFactory.getTableData(inputParams, callback)
}
function callback(lmsRecords, lmsCount){
// call back implementaion
}
That's because you are not invoking you factory function only aasigning it's reference to the controller.
If you want the $scope.branchSearch method to get the data from the factory you should it like this:
$scope.branchSearch = function (code){
$scope.data = LMSAppFactory.getTableData(params, code); // <= i assume -code- is your calllback
}
This way you invoke the function and send it the code parameter you fgot from the caller function
I have multiple functions inside of my factory and I cannot call my saveCharacter function from a button click using ng-click. The getCharacters function works just fine. Sorry in advance for the repost, I have gone over many different examples and cannot solve my particular issue with those. I can see my functions when I log the xmlService, but i'm not sure why it won't call to it. I was trying to return a post to a PHP file in saveCharacter, but changed to a string return to try to test to see what my issue was.
Thanks again for any help.
(function(){
var app = angular.module('arena', []);
app.factory('xmlService', function($http){
var factory = {};
factory.getCharacter = function getCharacter(){
return $http.get('xml/characterTemplate.xml');
};
factory.saveCharacter = function saveCharacter(){
return "hello";
//return $http.post('php/crud.php');
};
return factory;
});
app.controller('FighterController', ['$scope','xmlService', function($scope, xmlService){
this.fighterList = fighterList;
$scope.saveFighter = function saveFighter(){
console.log(xmlService);
xmlService.saveCharacter.success(function(data){
console.log(data);
});
}
function loadFighters(){
xmlService.getCharacter().success(function(data){
var x2js = new X2JS();
var charactersList = x2js.xml_str2json(data);
for(var i = 0; i < charactersList.characters.character.length; i++)
{
var currentFighter = charactersList.characters.character[i];
fighterList.push(currentFighter);
}
$scope.FighterController = charactersList;
});
}
loadFighters();
}]);
var fighterList = [
];
})();
Other questions I had while writing my first Angular app, what is the point of the code:
$scope.FighterController = charactersList;
does that allow me to access the returned data on the view side? do I have to reset the scope in my saveFighter function to cause my button to work?
Am I setting the dependencies correctly for my app.controller, and is that dependency injection?
Thank you all, and any comments on how my code is setup are greatly appreciated!
You haven't really explained what you did to fix this issue, so I'll explain it.
Here, you are trying to call xmlService.saveCharacter.success():
xmlService.saveCharacter.success(function(data){
console.log(data);
});
But xmlService.saveCharacter is a function. It has no success property; success is undefined. So this gives the error you were seeing.
You need to call xmlService.saveCharacter():
xmlService.saveCharacter().success(function(data){
console.log(data);
});
But this is still a problem because the saveCharacter() function returns the string "hello". This string doesn't have a success property. Yet again success is undefined, so now that causes the same error.
To fix that error, you just need to remove the return "hello"; and uncomment the code you had commented out:
factory.saveCharacter = function saveCharacter(){
return $http.post('php/crud.php');
};
Fixing those two problems should remedy your issue.
You are missing invoking a function with () change code to:
$scope.saveFighter = function saveFighter(){
console.log(xmlService);
xmlService.saveCharacter().success(function(data){
// ----------------------^
console.log(data);
});
}
$scope.FighterController = charactersList;is assigning data of characterList to scope variable and scope variable are accessible in html scope is like a bridge between controller and views.
I recommend you to start reading angularjs
I adjusted my factory to this structure and now I can call my functions.
app.factory('xmlService', function($http){
var factory = {
getCharacter: function(){
return $http.get('xml/characterTemplate.xml');
},
saveCharacter:function(){
console.log('hello?');
return $http.post('php/crud.php');
}
};
return factory;
});
in my controller
$scope.saveFighter = function(){
console.log(xmlService);
xmlService.saveCharacter().success(function(data){
console.log(data);
});
}
function loadFighters(){
xmlService.getCharacter().success(function(data){
var x2js = new X2JS();
var charactersList = x2js.xml_str2json(data);
for(var i = 0; i < charactersList.characters.character.length; i++)
{
var currentFighter = charactersList.characters.character[i];
fighterList.push(currentFighter);
}
$scope.FighterController = charactersList;
});
}
loadFighters();
I am working on setting up an HTML5 GeoLocation script and I would like to store the zip code in a cookie but for now I am just trying to figure out how to pass the zip code variable into another function.
Here is my script to reverse geo-code based on lat/long:
function retrieve_zip(callback)
{
try { if(!google) { google = 0; } } catch(err) { google = 0; } // Stupid Exceptions
if(navigator.geolocation) // FireFox/HTML5 GeoLocation
{
navigator.geolocation.getCurrentPosition(function(position)
{
zip_from_latlng(position.coords.latitude,position.coords.longitude,callback);
});
}
else if(google && google.gears) // Google Gears GeoLocation
{
var geloc = google.gears.factory.create('beta.geolocation');
geloc.getPermission();
geloc.getCurrentPosition(function(position)
{
zip_from_latlng(position.latitude,position.longitude,callback);
},function(err){});
}
}
function zip_from_latlng(latitude,longitude,callback)
{
// Setup the Script using Geonames.org's WebService
var script = document.createElement("script");
script.src = "http://ws.geonames.org/findNearbyPostalCodesJSON?lat=" + latitude + "&lng=" + longitude + "&callback=" + callback;
console.log(script.src);
// Run the Script
document.getElementsByTagName("head")[0].appendChild(script);
}
function callback(json)
{
zip = json.postalCodes[0].postalCode;
country = json.postalCodes[0].countryCode;
state = json.postalCodes[0].adminName1;
county = json.postalCodes[0].adminName2;
place = json.postalCodes[0].placeName;
alert(zip);
}
$('#findLocation').click(function(event) {
event.preventDefault();
console.log(zip); // This is giving me undefined currently
});
So basically, in the callback function, I want to store the zip code as a variable(rather than displaying it in an alert) and then in the on click function at the bottom, I want to be able to display the zip code that was stored in the previous callback function.
Any help greatly appreciated, still pretty new to Javscript/jQuery, thanks!
You could set zip as a 'global' variable by including it outside of the function at the top of the document like so:
var zip;
...
Alternatively, you may consider defining an object at the 'global' level and using it as a namespace to store variables like so:
window.address = {};
function callback(json){
address.zip = json.postalCodes[0].postalCode;
address.country = json.postalCodes[0].countryCode;
address.state = json.postalCodes[0].adminName1;
address.county = json.postalCodes[0].adminName2;
address.place = json.postalCodes[0].placeName;
}
$('#findLocation').click(function(event) {
event.preventDefault();
console.log(address.address);
console.log(address.zip);
...
});
I hope this helps!
Define var zip at very begining of code. You haven't defined it.
I haven't tried, but it should solve your problem.
Also, it seems that you forgot to define other variables in callback function as well.
What I would do, is to avoid the anonymous function in the event handler, that is, create a new named function -which gives you the added benefit of traceability during debugging- and then use that function as the event handler callback:
function eventHandlerFunction(event) {
var zip;
event.preventDefault();
zip = eventHandlerFunction.zip;
console.log(zip);
}
function callback(json) {
var zip;
zip = doSomethingWithJsonToGetTheZip();
eventHandlerFunction.zip = zip;
}
$("#findLocation").click(eventHandlerFunction);
Or, better yet, code this as a module and then you have member encapsulation and you can share variables amongst functions without modifying the global object. You never know when another library will modify the same global member that you are using.
var yourModule = (function($) {
var zip;
function retrieveZip(callback) {
// your code
}
function callback(json) {
// do something with json
zip = json.zip; // or whatever
}
$("#findLocation").click(function(event) {
event.preventDefault();
console.log(zip); // zip is visible in the parent scope + this scope
});
}(jQuery));
I just want to use a variable from outside of the function, but I am not sure what I have to do for that...
Is var myRequest = a; line enough to use this variable in the function?
Because I saw such an example: var myRequest = e.which;
I am asking this because I did not get a succesful result for my request.
I am think that it is not working as I expected because ajaxFunction(3) working diffirent than writing send.php?goto=3 into address bar of my browser.
You can see the following codes:
function ajaxFunction(a)
{
var ajaxRequest;
try {
ajaxRequest = new XMLHttpRequest();
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("Your browser broke!");
return false;
}
}
}
ajaxRequest.open("GET", "send.php?goto=" + a, true);
ajaxRequest.send();
}
If you want to use a variable outside a function you have to use a global scope variable, example (using jQuery ajax)
var globalA = null;
$(document).ready(function(){
var localA1 = null;
$.ajax({
"url":"http://someurl.com/",
"type":"POST",
"dataType":"json",
"success":function(incomingData){
var localA2 = incomingData //localA2 only useable inside this function
localA1 = incomingData; //localA1 being set here still can only be used here as code within the "ready" function has already been executed and will see it as null
globalA = incomingData; //Now any further code should use globalA as it now contains useable data
doSomethingWithData();
},
"error":function(xhr,msg) {
alert("Ajax Error:"+msg);
}
});
alert(localA1); //Will give alertbox with null in it as localA1 has not been set.
});
function doSometingWithData() {
alert(globalA); //You can now use the data in whatever function makes reference to globalA
}
Of course in this example you could have just passed the data straight to doSomethingWithData() and processed it there.
You could take a look at the jQuery $.globalEval for instantiating a variable globally inside of your AJAX success function.
$.ajax({
url: "send.php",
success: function (data) {
$.getScript("somescript.js", function(data) {
$.globalEval("var something = new Whatever;");
});
});
The $.getScript portion is a helpful little snippet if you find you need to load an external JS file in your ajax call, and make its assets globally available. You can then use $.globalEval to instantiate a variable inside of your AJAX function.
Documentation for $.globalEval
Documentation for jQuery AJAX
You don't a function wrapper for setting a value to a variable.
var myRequest = a;
That is good enough.
After thought revision
in a very basic way a variable can be created on its own like a place holder.
var myRequest;
when you get to the function (say you have a series of functions.
You could do something like this.
function(myRequest=a);
if the function has more than one argument it can look like this.
function(myRequest=a,myConcern=b); as you have it stated in the
var arg1 = 1;
var arg2 = 2;
var arg3 = 3;
ajaxRequest.open(arg1,arg2,arg3);
I hope this is helpful and yes, some more info would help (like the poster below stated).
I am currently in the process of making my first Titanium iPhone app.
In a model I got:
(function() {
main.model = {};
main.model.getAlbums = function(_args) {
var loader = Titanium.Network.createHTTPClient();
loader.open("GET", "http://someurl.json");
// Runs the function when the data is ready for us to process
loader.onload = function() {
// Evaluate the JSON
var albums = eval('('+this.responseText+')');
//alert(albums.length);
return albums;
};
// Send the HTTP request
loader.send();
};
})();
and I call this function in a view like:
(function() {
main.ui.createAlbumsWindow = function(_args) {
var albumsWindow = Titanium.UI.createWindow({
title:'Albums',
backgroundColor:'#000'
});
var albums = main.model.getAlbums();
alert(albums);
return albumsWindow;
};
})();
however it seems like the call to the model (which fetches some data using HTTP) doesn't wait for a response. In the view when I do the alert it haven't received the data from the model yet. How do I do this in a best-practice way?
Thanks in advance
OK,
Something like this,
function foo(arg1, callback){
arg1 += 10;
....
... Your web service code
....
callback(arg1); // you can have your response instead of arg1
}
you will call this function like this,
foo (arg1, function(returnedParameter){
alert(returnedParameter); // here you will get your response which was returned in above function using this line .... callback(arg1);
});
so here arg1 is parameter (simple parameter like integer, string etc ... ) and second argument is your call back function.
Cheers.
What you need is Synchronous call to web service, so that it will wait till you get the response from the service.
To achieve this in java script you have to pass callback function as parameter and get the return value in callback function instead of returning value by return statement.
Actually coding style you are using is new for me because i am using different coding style.
But the main thing is you have to use call back function to retrieve value instead of return statement. Try this and if you still face the problem than tell me i will try to give an example.
the callback way like zero explained is nicely explained, but you could also try to get it handled with events.
(function() {
main.ui.createAlbumsWindow = function(_args) {
var albumsWindow = Titanium.UI.createWindow({
title:'Albums',
backgroundColor:'#000'
});
var status = new object(), // eventlistener
got_a_valid_result = false;
// catch result
status.addEventListener('gotResult',function(e){
alert(e.result);
got_a_valid_result = true;
});
// catch error
status.addEventListener('error',function(e){
alert("error occured: "+e.errorcode);
git_a_valid_result = true;
});
var albums = main.model.getAlbums(status);
// wait for result
while (!got_a_valid_result){};
return albumsWindow;
};
})();
and your model may something like
main.model.getAlbums = function(status) {
var loader = Titanium.Network.createHTTPClient();
loader.open("GET", "http://someurl.json");
loader.onload = function() {
var albums = eval('('+this.responseText+')');
status.fireEvent('gotResult',{result:albums});
return albums;
};
loader.onerror = function(e){
status.fireEvent('error',{errorcode:"an error occured"});
};
// Send the HTTP request
loader.send();
};
Just as a suggestion, try to use JSON.parse instead of eval as there are risks involved with using eval since it runs all javascript code.
I think that the solution The Zero posted is likely better for memory management, but I'm not totally sure. If you do and eventListener, be aware of the following
(see https://wiki.appcelerator.org/display/guides/Managing+Memory+and+Finding+Leaks)
function doSomething(_event) {
var foo = bar;
}
// adding this event listener causes a memory leak
// as references remain valid as long as the app is running
Ti.App.addEventListener('bad:idea', doSomething);
// you can plug this leak by removing the event listener, for example when the window is closed
thisWindow.addEventListener('close', function() {
// to remove an event listener, you must use the exact same function signature
// as when the listener was added
Ti.App.removeEventListener('bad:idea', doSomething);
});