This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
Hello this is my second time using AngularJS... I create a http request and no problem with it.
But the question is, how i can get the result of this request or put in a variable ?
var cust_url = "RETURN A JSON";
var FINAL_FILE = "";
$http.get(cust_url)
.then(function (response) {
$scope.details = response.data;
//--> do multiple modify to response.data
FINAL_FILE = 'something';
});
$scope.data = {
/*USE HERE --> FINAL_FILE
return -> undefined on console if i try to access to FINAL_FILE
*/
};
Like the example... sorry i think is a stupid error. Thanks for your time.
$http request is asynchronous, this is the reason that you get the undefined value. If you want to use the response data, you have to do it inside the then callback, where the data are available, like this:
$http.get(cust_url)
.then(function (response) {
$scope.details = response.data;
//--> do multiple modify to response.data
FINAL_FILE = 'something';
// here use the $scope.details or call a function to use data
$scope.data = { };
});
Return data to the .then method and save the promise:
var finalFilePromise = $http.get(cust_url)
.then(function (response) {
$scope.details = response.data;
//--> do multiple modify to response.data
FINAL_FILE = 'something';
return FINAL_FILE;
});
To use, extract the data from the promise:
$scope.data = {
//USE HERE --> FINAL_FILE
finalFilePromise.then(function(FINAL_FILE) {
console.log(FINAL_FILE);
});
};
For more information, see
AngularJS $q Service API Reference - Chaining Promises
Related
This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 1 year ago.
i'm implementing Toast Ui Calendar in my php/js app and in the flow of javascript execution the program encounter this function:
function setSchedules() {
cal.clear();
generateSchedule();
cal.createSchedules(ScheduleList);
refreshScheduleVisibility();
}
When i refresh the page to visualize the events retrived from db via axios and php function, the calendar is empty, then if a select month view or go back one week and come back to the current week the events are rendered.
The problem seam to reside in the function generateScedule() which is declared inside a schedules.js file and that declare and fulfill the ScheduleList array to pass to the createSchedules function, follow the code:
var ScheduleList = [];
function generateSchedule() {
axios({
method: 'post',
url: 'path-to-data',
})
.then(function (response) {
ScheduleList = [];
let data = response.data;
for(let key in data){
ScheduleList.push(data[key]);
};
})
.catch(function (error) {
console.log(error);
});
return ScheduleList; //with or without this return the result doesn't change
}
It's like if the array ScheduleList at first is returned empty (whithout waiting) while the function is still fulfilling it, console.log inside varoius parts of the function confirm it.
If i fulfill the array manually with pasted json data, everything is returned immediately an fine.
I know it has probably to do with javascript stacks etc..
Any help would be appreciated.
Thanks a lot in advance!
Because axios is async so the ShceduleList stay empty,
the return is executed before the loop of data.
Try this :
function generateSchedule() {
return axios({
method: 'post',
url: 'path-to-data',
})
.then(function (response) {
var ScheduleList = [];
let data = response.data;
for (let key in data) {
ScheduleList.push(data[key]);
};
return ScheduleList;
})
.catch(function (error) {
console.log(error);
});
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
There is this small function that should logically returns always, but I am getting undefined :-
function hasAccess() {
var dataObj = {
"id" : $scope.groupId
};
$http.post('http://vlinux:9099/GetItems', dataObj).then(
function(response) {
var result = response.data.result;
if(result.includes($scope.screenId)) {
return "ok";
} else {
return "nok";
}
});
}
I started getting downvotes, so wuickly adding, I debugged it and saw http call is bringing expected response and flow is jumping to the right if/else block. Problem is when I am calling this function in a variable its storing undefined.
The call is simple too :-
var allow = hasAccess();
$http.post is not synchronous, but asynchronous.
Thus, all that you have after $http.post is a promise, not the boolean you are expecting.
The documentation show wells how to provide a "callback" to your function, in case of success as well as failure :
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
// for example : manageWHenOk
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
// for example : manageWHenKO
});
Your function return a result only if the request is fine. If there is an error your function do nothing! I suggest you to add a catch function.
function hasAccess() {
var dataObj = {
"id" : $scope.groupId
};
$http.post('http://vlinux:9099/GetItems', dataObj).then(
function(response) {
var result = response.data.result;
if(result.includes($scope.screenId)) {
return "ok";
} else {
return "nok";
}
}).catch(function (error) {
// do something
});
}
If you still have undefined it means that your template is loaded before to obtain the response. In order to resolve that you can do the request in the resolve method of the $stateProvider.
This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 6 years ago.
The following code is in my controller - when I reach the console.log() line, nothing is printed out. The AJAX call returns a valid array. I tried using $scope.$apply but I got an process already in progress error, I'm assuming because using $http automatically starts the digest cycle:
var mmyApp = angular.module('myApp',['ui.bootstrap']).controller('TasksController', TasksController);
function TasksController($scope, $http) {
$scope.transactions = [];
$http.get('transactions').then(function (response) {
$scope.transactions = response.data;
}, function (error) {
throw error;
});
console.log($scope.transactions);
}
$http.get is asynchronous. When you call your console.log, your GET request didn't return yet. You can move it inside the handle body to see that it works:
$http.get('transactions').then(function (response) {
$scope.transactions = response.data;
console.log($scope.transactions);
}, function (error) {
throw error;
});
You should know that AJAX calls made with $http in AngularJS are asynchronous, that is, they do not run in sequence with the rest of the code, unless you set it that way.
Therefore when the console.log is executed, the request still has not finished processing. The correct thing is that you run console.log after performing the assignment of the variable in the AJAX call, in this way:
var mmyApp = angular.module('myApp',['ui.bootstrap']).controller('TasksController', TasksController);
function TasksController($scope, $http) {
$scope.transactions = [];
$http.get('transactions').then(function (response) {
$scope.transactions = response.data;
console.log($scope.transactions);
}, function (error) {
throw error;
});
}
I have a json file. I want to get the data from that file using $http.get and store that in variable so that I can use it later in the controller. Something like this:
$http.get('items.json').success(function(response){
var data = response; //data can't be used outside this function
})
I want to use data outside the function.
You can do it in the below fashion:
var data;
$http.get('items.json').success(function(response){
data = response; //data can't be used outside this function
})
here data now will be accissible to all the methods of your controller.
But my suggestion is to make one angular service and put $http code inside it. And then inject this service
inside your controller and use it.
Below would be the code:
Service Code:
app.service('MyService', function($http) {
this.getData = function(successHandler, failureHandler) {
$http.get('items.json').then(function(response){
successHandler(response); //data can't be used outside this function
}, function(response) {
failureHandler(response);
})
}
});
Controller Code:
app.controller('MyCntrl', function($scope, MyService) {
var data;
function successHandler(res) {
data = res;
}
function failureHandler(res) {
data = res;
}
$scope.getData = function() {
MyService.getData(successHandler, failureHandler);
}
});
The above solution would help you to separate out the concerns related to service and controller and to make your application
more modular and maintainable.
You can create data outside that function. like
var data;
$http.get('items.json').success(function(response){
data = response; //data can't be used outside this function
});
But in this way also data will be undefined unless get call gives response, evenif you are using JSONP from local.
Ideal way to do this is using promises. as below
var callService = function(){
return $http.get('items.json').success(function(response){
return response; // Response variable will be input to promise
});
};
callService.then(function(data){
// this data variable will be equal to response.
});
Further reading on
https://docs.angularjs.org/api/ng/service/$q
dont create a variable inside call, declare that variable outside and just assign value for it.
var data;
$http.get('items.json').success(function(response){
data = response; //data can't be used outside this function
});
as all mentionned create the variable outside the function.
BUT USE THEN instead of success because it is depreceted
Deprecation Notice
The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error.
var data;
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
console.log(reponse); // response contain status , data, headers, config...
data = response.data ;
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
This question already has answers here:
$q promise with Underscore _each
(3 answers)
Closed 8 years ago.
I'm trying to load data from multiple sources and want to continue processing only after all data being loaded. Here is my code:
var tables = [];
$http
.get('/tables')
.then(function (response) {
_.each(response.data, function (table) {
tables.push(table);
});
})
// get detail data
.then(function () {
_.each(tables, function (table) {
$http.get('/tables/' + table)
.success(function (data) {
process(data);
});
});
})
.then(function () {
// after everything loaded
// run this function
});
Thanks for your help!
You should use the following:
.then(function () {
return $q.all(_.map(tables, function (table) {
return $http.get('/tables/' + table)
.success(process);
});
})
Unrelated to the main part of your question, but note that you don't need to define an all new anonymous function for .success if you're just going to pass the parameter into process().
See also: $q promise with Underscore _each