Browser can process scripts before handle post request. Conside I have the following sample
if (some true condition) {
console.log("ready to post")
restangular.all.post(RequestData).then(function(response){
//some post methods
console.log("response")
});
}
//then containing scripts
cosole.log('Hello')
....
output
ready to post
Hello
response
I expect to do the POST request before printing "Hello". How to overcome this?
In order to achieve what you want you should look into angularJS promises, since the POST request is asynchronous. For example check this link:
http://www.webdeveasy.com/javascript-promises-and-angularjs-q-service/
The main idea is to first create a call that returns a deferred object, something like
this.myFunction = function (myForm) {
var deferred = $q.defer();
$http.post(myURL, myForm)
.success(function (data) {
//resolve the promise
deferred.resolve('SUCCESS');
})
.error(function (data) {
//reject the promise
deferred.reject('ERROR');
});
//return the promise
return deferred.promise;
}
and then call it like
var myPromise = this.myFunction ($scope.modalForm);
// wait until the promise return resolve or eject
//"then" has 2 functions (resolveFunction, rejectFunction)
myPromise.then(function(resolve){
// do stuff here, the post request is successfully finished
}, function(reject){
return;
});
Alternatively, any code you want to be executed after the POST request, you can put it in the success function of the request.
Related
I'm creating little app using API TheMovie DB. My function responsible for fetching data looks like this:
movieSearch(term){
const request = axios.get(`${ROOT_URL}${API_KEY}&query=${term}`);
console.log(request);
}
Result in console looks like this:
link
How can i reach "response" field?
The axios.get() returns a Promise object (what you see in the screenshot). To get the response of HTTP request, you need to invoke that Promise object's then() function:
axios.get('http://<your address>')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
For more information on Promise and its usage, you can refer to Promise - JavaScript | MDN.
I am working on this code and I have a really weird issue. I am using AngularJS $http request, and trying to run a success or error afterwards. I am currently getting a 404 from the server (the client says) but the server isn't barfing up a 404 (in fact it says it sent a 200 response).
This $http post doesn't hit either the 'success' or 'error' handlers and I don't know what to do for debugging it.
All other functions using RequestService work perfectly.
var refreshBusinesses = function() {
console.log("refreshBusinesses");
RequestService.post('user/managed_businesses', {}).then(function(businesses){
console.log('got busineses ', businesses)
$scope.businesses = businesses
}, function(error){
console.log("ERROR!");
$scope.error = error.message;
console.log('business refresh error ', error)
})
}
Most probably your service RequestService does not handle promise properly. I believe it is a wrapper around angular's $http. If so, probably it does not reject promise on error, but simply returns some value.
So to solve it check your RequestService that it handles error situation properly:
$http.post('url', data).then(
function(res) {
return res;
},
function(error) {
var deferred = $q.defer();
return deferred.reject(error);
});
$q docs can be found here https://docs.angularjs.org/api/ng/service/$q
I need to append the necessary HMAC headers to a request. This should not be very difficult however I am starting to get frustrated. What is wrong with the following code. The actual http call I am doing works; I have run this call myself and it returns the necessary data. It does not work inside the interceptor.
I merely want to get the current implementation working before I add whitelist or blacklist and other customizable data for this interceptor. This is not a question about hmac however but with promises.
The error in this interceptor is with the entire promise line starting at $http(...). When i remove this block and use it as is (minus promise execution) it works fine. As soon as i uncomment the line it gets stuck in a loop and crashes chrome. Everywhere I have read says this is how it is done, but this clearly does not work.
function requestInterceptor(config){
var $http = $injector.get('$http');
var deferred = $q.defer();
$http.get(hmacApiEndpoint, {cache: true}).then(function(data){
console.log('HMAC - Success', data)
deferred.resolve(config)
}, function(config){
console.log('HMAC - Error', config)
deferred.resolve(config)
})
return deferred.promise;
}
return {
request: requestInterceptor
};
Does this have something to do with the fact that angulars $http promise is a different implementation than that of '$q'?
It doesn't look like you are actually amending the config with the newly obtainted HMAC.
Also, you'd need to protect against your requestInterceptor intercepting the call to obtain the HMAC, thus resulting in an infinite loop.
And lastly, you don't need deferred here - just return the promise produced by $http (or $http.then()):
function requestInterceptor(config){
var $http = $injector.get('$http');
// just return, if this is a call to get HMAC
if (config.url === hmacApiEndpoint) return config;
return $http.get(hmacApiEndpoint, {cache: true})
.then(function(response){
console.log('HMAC - Success', response.data)
// not sure where the HMAC needs to go
config.headers.Authorization = response.data;
return config;
})
.catch(function(){
return $q.reject("failed to obtain HMAC");
});
}
return {
request: requestInterceptor
};
I am trying to create a Meteor method with a HTTP get request. I am getting back a result, but I can't get my callback on the client side to return the result. The callback needs to wait for the HTTP request to get back a result before it returns the callback. I am getting the data successfully from the HTTP request, so that is not the problem.
Any suggestions on how to get this working?
Meteor.methods({
getYouTubeVideo: function (id) {
check(id, String);
var params = {
part:'snippet, status, contentDetails',
id:id,
key:Meteor.settings.youtube.apiKey
};
HTTP.get('https://www.googleapis.com/youtube/v3/videos', {timeout:5000, params:params}, function(error, result){
if (error) {
throw new Meteor.Error(404, "Error: " + error);
return;
}
console.log(result);
return result;
});
}
});
You need to use the synchronous version of HTTP.get, just like this :
var result=HTTP.get('https://www.googleapis.com/youtube/v3/videos', {timeout:5000, params:params});
return result;
If you use the asynchronous version with a callback like you did, you're facing the common problem of having to try returning the result in the callback (which won't work) instead of in the method, which is what you should do.
Note that synchronous HTTP.get is only available in the server-environment, so put your method declaration under server/
My controller has all the required dependencies injected.
$scope.connect = function(url) {
var defer = $q.defer();
var promise = $http.get(url).then(function (response) {
$timeout(function(){
defer.resolve(response);
},10000);
defer.resolve(response);
$scope.$apply(); //$rootScope.$apply();
});
return defer.promise;
};
$scope.mymethod = function(){
$scope.globalMydata[];
console.log("before the http get");
$scope.connect("MY_URL").then(function(data) {
console.log("called!", data);
console.log("INSIDE the http get");
$scope.mydata = data;
//$scope.globalMydata.push(data);
});
console.log("after the http get ");
//do some processing of the returned data here
var dataHolder = $scope.mydata;
return calculatedValue;//value from procesing
}
When the code is executed "INSIDE the http get" is invoked as the last debug log. I get the results from the get call but since its returned later, I am unable to do any processing with it. This is the exactl reason why we promises right? I need the promised data to do some processing inside the controller.
Any issue in my promise implementation??
I'm not sure whether I get your question, but it looks like you've built a promise interseptor, but from your question it looks like you want just the regular promise behaviour. So I'll try that..
I'm not an angular expert but I do use $http promises a lot and here's how I do it.
I register the $http call as a service, like this:
app.service('ajax',function(host,$http){
this.post = function(api,data,cb){
$http.post(host + api,data).success(cb)
};
this.get = function(api,cb){
$http.get(host + api).success(cb)
}
});
host is a predefined module.value. I inject this service into every controller that needs to call http requests and operate them like this:
ajax.post('users', UserToken, function(data){
console.log('Users points: ' + data.points)
})
As I understand $http has promises built in, so there's no need for q and defere, it's all done at the background. ajax.post calls the service, which sends data to host + 'users', server-side looks for user by his token and return some data with one key by the name of points with a value of the users points. Client-side: upon successful reply from the server it proceeds to the cb function which then console logs the user points.
So I can do whatever modification I need to the promise inside that cb function, since it is not called before a successful reply from the server.
The success and error methods have a few more optional arguments, check them out here.