AngularJS service to variable - javascript

Is there a way to store data to a variable?
I tried:
$scope.another =
function(){
var new_data;
userService.getInfo().success(function(data){
new_data = data;
});
return new_data;
};
var data = $scope.another();
but it returns 'undefined' in the console log. Thank you
EDIT
I now get an empty array for new_data .
var new_data = [];
$scope.another =
function(callback){
userService.getInfo().success(function(data){
paymentService.getCashierParams({ "cardNumber": data.cardNumber}).success(function(data){
gameService.getAllgames({ "PID":data.GetCashierParameters.PID, "limit": 6, "skinID": 1}).success(function(data) {
callback(data.data.GetFlashGamesResult.Data.FlashGame);
});
});
});
};
$scope.another(function(result){
new_data = result;
});
console.log(new_data);

You need to think about this problem differently. Your getInfo method returns a promise. A promise's success callback is never immediately called. It may be called sometime in the future, but in the meantime your code will continue executing and the return value of $scope.another will be undefined.
Instead, place whatever logic you wish to execute within the success callback.
userService.getInfo().success(function (data) {
// Do stuff with data.
});
If you are not used to working with asynchronous data, this may seem weird. But it is much better than the alternative, which is hanging the page for potentially many seconds while a network request, database read, etc, completes.
If you are worried about indentation, you can create separate function(s) to handle the data.
function processData(data) {
// Process stuff...
return data;
}
function handleData(data) {
data = processData(data);
console.log(data);
}
userService.getInfo().success(handleData);

This is due to the asynchronous function that you called. Try to use callback instead. Something like this:
$scope.another =
function(fn){
userService.getInfo().success(function(data){
fn(data);
});
};
var data = $scope.another(function(doSomething) {
alert(doSomething);
return doSomething;
};

Related

Call $http inside AngularJS function

I've been trying for a while to get the data from this call, but it always returns "undefined"
httpCall = function(sTformName) {
let sURL = "https://urlthisone/api/",
response;
$http.get(sURL)
.success(function(data) {
response = data;
});
}
Any ideas on what I'm doing wrong?
Thanks in advance.
You can return and resolve the promise...
httpCall = function(sTformName) {
let sURL = 'https://urlthisone/api/',
return $http.get(sURL);
}
httpCall('myForm').then(response => {
console.log(response.data);
});
$http.get is an asynchronous call and must be handled accordingly, in this case, by resolving the returned Promise
You're making an async call, and it will not return a value. It calls success and inside success you need to use a callback method in order to get the value you want, and work with it.
function doSomethingWithTheData(data) {
// process the data here.
}
httpCall = function(sTformName, callback) {
let sURL = "https://urlthisone/api/",
response;
$http.get(sURL)
.success(function(data) {
callback(data); // here's where we call the callback
});
}
// call it with the callback
httpCall(fornName, doSomethingWithTheData);
Please, see documentation - https://docs.angularjs.org/api/ng/service/$http#get
According to it, if you use angular.js 1.4.3+, $http.get(sURL) returns promise. So you need $http.get(sURL).then(...)
Also, see $http.get(...).success is not a function might will help

JavaScript multiple promise issue with $.get

function getHiddenTable(){
var url = ".......";
var apptoken = "blahblah";
return $.get(url, {
act: "API_DoQuery",
clist: "7.8.6",
data: apptoken
});
}
function getRprTable(){
var url = "........";
var apptoken = "blahblah";
return $.get(url, {
act: "API_DoQuery",
clist: "3.60",
data: apptoken
});
}
function main(){
getHiddenTable().then(function(xml_hidden){
hiddenTable = xml_hidden;
console.dirxml(hiddenTable);
return getRprTable();
}).then(function(xml_rpr){
rprTable = xml_rpr;
console.dirxml(rprTable);
});
}
main();
getHiddenTable() returns a $.get request and getRprTable() also returns a $.get request
Both of these functions return two separate xml files that contain different data. I assign both xml files to two separate global variables so they have scope to other function that I need to use them in. However, both console statements display the initial request from getHiddenTable(). But why? And what can I do to fix this?
Update
Hey guys, thanks for the help. I found out my problem with much frustration and actually utilized $.when, from the person who provided the idea in the comments.
$.when(getHiddenTable(), getRprTable()).done(function(xml_hidden, xml_rpr){
console.dirxml(xml_hidden[0]);
console.dirxml(xml_rpr[0]);
});
Accessing the data value of the callback function objects can be done by simply accessing the 0th index.
Thanks
You'll likely want to use Promise.all() to run multiple promises at once and return the results of all the promises once they have all finished.
Example:
Promise.all([getHiddenTable(), getRprTable()])
.then(function(results) {
let hiddenTable = results[0];
let rprTable = results[1];
// do stuff with your results
});
Hope that helps

AJAX get and callbacks

I'm trying to make a variable depend on the callback from an AJAX get function, however; I can't seem to get it working. I want to make sure that defaults.context always has a value before proceeding any other code.
What am I doing wrong or how can I achieve this in a proper way?
var defaults = {
currentCase: undefined,
context: {}
}
// Set defaults
function initDefaults(){
defaults.currentCase = getCurrentCase();
defaults.context = getContext(defaults.currentCase, function(object){
console.log(object); // logs the right data
return object;
});
console.log(defaults.context); // logs undefined
}
initDefaults();
// Get the ID of the current case
function getCurrentCase(){
return global_vars.project_ID;
}
function getContext(id, callback){
var obj = {};
$.get(global_vars.template_url + "/includes/load-project-context.php?id=" + id, function(data) {
obj = JSON.parse(data);
}).complete(function() {
callback(obj);
});
}
Thanks in regards,
Enzio
You can use something like
global_vars.template_url + "/includes/load-project-context.php?id=" + id, function(data) {
obj = JSON.parse(data);
}).complete(function() {
callback(obj);
}).fail(function() {
callback(error);
});
This is callback chaining. You can use other callbacks to handle other use cases.
Please check How to know when all ajax calls are complete
You will find there all what you need with quite good explanation
May be you should continue the further code in ajax callback.
// Set defaults
function initDefaults() {
defaults.currentCase = getCurrentCase();
getContext(defaults.currentCase, function(object) {
defaults.context = object; // Continue your code inside here
console.log(defaults.context); // Logs the right data
return object;
});
// This will still return `undefined` because this line will be executed
// before the ajax request finishes.
console.log(defaults.context);
}

Any better way to combine multiple callbacks?

I need to call an async function (with loop) for multiple values and wait for those results. Right now I'm using the following code:
(function(){
var when_done = function(r){ alert("Completed. Sum of lengths is: [" + r + "]"); }; // call when ready
var datain = ['google','facebook','youtube','twitter']; // the data to be parsed
var response = {pending:0, fordone:false, data:0}; // control object, "data" holds summed response lengths
response.cb = function(){
// if there are pending requests, or the loop isn't ready yet do nothing
if(response.pending||!response.fordone) return;
// otherwise alert.
return when_done.call(null,response.data);
}
for(var i=0; i<datain; i++)(function(i){
response.pending++; // increment pending requests count
$.ajax({url:'http://www.'+datain[i]+'.com', complete:function(r){
response.data+= (r.responseText.length);
response.pending--; // decrement pending requests count
response.cb(); // call the callback
}});
}(i));
response.fordone = true; // mark the loop as done
response.cb(); // call the callback
}());
This isn't all very elegant but it does the job.
Is there any better way to do it? Perhaps a wrapper?
Async JS to the rescue (for both client-side and server-side JavaScript)! Your code may look like this (after including async.js):
var datain = ['google','facebook','youtube','twitter'];
var calls = [];
$.each(datain, function(i, el) {
calls.push( function(callback) {
$.ajax({
url : 'http://www.' + el +'.com',
error : function(e) {
callback(e);
},
success : function(r){
callback(null, r);
}
});
});
});
async.parallel(calls, function(err, result) {
/* This function will be called when all calls finish the job! */
/* err holds possible errors, while result is an array of all results */
});
By the way: async has some other really helpful functions.
By the way 2: note the use of $.each.
You can use the jQuery Deferred object for this purpose.
var def = $.when.apply(null, xhrs) with xhrs being an array containing the return values of your $.ajax() requests. Then you can register a callback def.done(function() { ... }); and use the arguments array-like object to access the responses of the various requests. to properly process them, remove your complete callback and add dataType: 'text' and use the following callback for done():
function() {
var response = Array.prototype.join.call(arguments, '');
// do something with response
}

Return array from JSON file with JQuery?

I have a JSON file that contains the following:
[{name:joe,number:4},{name:ralph,number:76}]
Simply put, I'm trying to create a function that returns that as an array:
function createArray(){
x = $.getJSON("/names.json", function(json) {
var myArray = [];
$.each(json, function() {
myArray.push(json);
});
return myArray;
});
return x;
}
This is not working, I'm not sure what part of it doesnt make sense
You are doing an asynchronous request. $.getJSON does not return the result of your callback.
You need to pass a callback into your createArray function. Also, if your JSON data is already an array, you don't need to process the response data.
function createArray(cb){
$.getJSON("/names.json", cb);
}
So for example you'd change this:
var myArray = createArray();
// Process myArray
into this:
createArray(function(myArray) {
// Process myArray
});
The problem is that you can't just assign the result of a network request. When you call getJSON, you start a network request, but after the request starts, the JS will keep running other stuff. The get the result of an asynchronous request, you need to use a callback that will process that data and do something with it.
Like loganfsmyth said, you're not taking into account that $.getJSON is asynchronous, and it's not going to return what you think it is (it actually returns a jqXHR Object. Write your code to handle the asynchronous nature using closures:
function createArray(cb){
$.getJSON("/names.json", function(json) {
var myArray = [];
$.each(json, function() {
myArray.push(json);
});
cb(myArray);
});
}
createArray(function(array) {
//your array is available here
console.log(array);
}
Your keys and values should be Strings
[{"name":"joe", "number":4},{"name":"ralph", "number":76}]
and this
$.each(json, function() {
myArray.push(json);
});
should become
$.each(json, function(key, val) {
if(myArray[key] == undefined)
{ myArray[key] = new Array();
}
myArray[key].push(val);
});
What you get from 'json' is an array.
try this,
var ar = [{
"name": "joe",
"number": "4"},
{
"name": "ralph",
"number": "76" }];
alert(ar[0].name);​
This would alert the name "joe".
ar[0] is the first element of the array and in your case this is an object with properties name and number. You can get/set them in normal way.
var myArray = [];
$.getJSON("/names.json", function(json) {
myarray=json;
});
NowmyArray is an array with your Objects.
You can't do that, your function will return a promise object, but never the json response itself. The response will be available from the promise only after the request is complete (which is not immediately after function return because the request is asynchronous).
Why don't you just use the json from the callback? I mean this:
function createArray(){
$.getJSON("/names.json", function(json) {
// Whatever you need to do with your json,
// do it here. This code will run after
// createArray returns. And you can't
// return anything from here, it's useless.
// Actually, you don't even need the outer
// createArray function.
});
}

Categories