I have the following function in my controller.
RestRequestsSrvc.getUserDetail()
.then(
function (response) {
$scope.user.userDetail = response;
},
function (error) {
// TODO
});
If I type
console.log(RestRequestsSrvc.getUserDetail());
the console logs a promise. I want to set a variable the the response. How can I modify my code so that I get the response instead of a promise?
Return a promise because your request is async.
You should wait the response,
Putting the console.log inside the callback function should print your info.
RestRequestsSrvc.getUserDetail()
.then(
function (response) {
$scope.user.userDetail = response;
console.log(response);
},
function (error) {
// TODO
});
You can do the console.log into the promise .then
RestRequestsSrvc.getUserDetail()
.then(
function (response) {
$scope.user.userDetail = response;
console.log(response);
},
function (error) {
// TODO
});
The thing is that when you call the function it will be executed but will not wait for the result, that's why you get a promise. The .then stuff is called once the request is done executing. That's where you handle your success or error callbacks.
Requests to the server are asynchronous, meaning that you must handle the response inside the callback.
You could use async false flag but this is not recommended if you have independent modules that executed later in the code.
Related
I have a few problem while integrating api from OpenWeather.
I can successfully log the response data value from the api. But when i call from another component with .then(), throw me the error.
The following is my api.js call with axios
function getFiveDayForcast(cityName) {
axios.get(`http://api.openweathermap.org/data/2.5/forecast/daily?q=${cityName}&type=accurate&APPID=${apiKey}&cnt=5`)
.then(function(response){
// console.log("response" , response.data);
return response.data;
})}
module.exports= {getFiveDayForecast:getFiveDayForecast}
This is when i call back from my Component
componentDidMount(){
let city = queryString.parse(this.props.location.search).city;
this.makeRequest(city);
}
makeRequest =(city) => {
//set loading false
this.setState(()=> ({loading:false}));
api.getFiveDayForecast(city).then((response) => {
console.log(response)
})
}
And it throw
TypeError: Cannot read property 'then' of undefined
Would be nice if someone can explain in details about it. I am also reading documentation as well. Thanks in advance.
Posting my answer here so more people can see.
Referring to Returning an Axios Promise from function
The complaint is that a function needs to return something in order for the then chain to know what to do. The function preceding the then chain is not returning anything, so the function inside then then chain doesn't know what to do.
Axios takes care of this for the get action, but you aren't directly chaining the get method to then. Instead, you are chaining a method you created, getFiveDayForcast.
You should change getFiveDayForcast(cityName) (btw 'Forecast' is the right spelling) to
function getFiveDayForcast(cityName) {
const request = axios.get(`http://api.openweathermap.org/data/2.5/forecast/daily?q=${cityName}&type=accurate&APPID=${apiKey}&cnt=5`)
.then(function(response){
// console.log("response" , response.data);
return response.data;
})
return request;
}
You need to return the Promise from your Function getFiveDayForcast.
function getFiveDayForcast(cityName) {
return axios.get(`http://api.openweathermap.org/data/2.5/forecast/daily?q=${cityName}&type=accurate&APPID=${apiKey}&cnt=5`)
.then(function(response){
// console.log("response" , response.data);
return response.data;
})
}
I'm a bit new to $q angular promises. Here is my code structure:
$q.all(promises).then(function(results) {
results.forEach(function(data, status, headers, config) {
console.log(status);
});
$scope.saveDocumentCaseState();
}, function errorCallBack(response) {
console.log('error while mass update case entries');
console.log(response);
$scope.submitToWsSuccessful = 2;
});
Is there a possibility to access the result of each promise when it has been executed before the next one?
So assuming that you receive an array with an arbitrary number of promises from an angular factory called promiseFactory:
var promises = promiseFactory.getPromises(); // Returns an array of promises
promises.forEach(function(p){
p.then(promiseSuccess, promiseError);
function promiseSuccess(){
// Do something when promise succeeds
}
function promiseError(){
// Do something when promise errors
}
});
$q.all(promises).then(allSuccess, allError);
function allSuccess(){
// All calls executed successfully
}
function allError(){
// At least one of the calls failed
}
I have this code
PedidosService.getProductbyID($scope.listProductos.ProductID).then(function (d) {
$scope.oneProduct = d.data.producto;
});
PedidosService is the name of my factory, getProductbyId is my http get request and $scope.oneProduct is the variable where i want store the result of this request.
factory.getProductbyID = function (id) {
return $http.get('/Pedidos/GetProduct/' + id);
}
factory is my Factory and getProductbyID is my function to call http request
I call this code in a button. The first time that I click in the button, it returns a empty response '[]' but the next times that I click the button, it works fine!!!.
Thanks for you help
As far as I know the $http.get returns a promise because that call is asynchronous. With that in mind a typical call to $http.get should be something like this:
$http.get('/someUrl', config).then(successCallback, errorCallback);
In your context I would have done it this way, so the factory returns a promise and in your controllers you will handle the success and error callback appropriately:
factory.getProductbyID = function (id) {
var deffered = $q.defer();
$http.get('/Pedidos/GetProduct/'+ id)
.then(function (result) {
deffered.resolve(result);
}, function (data) {
deffered.reject(data);
});
return deffered.promise;
}
I am using $http to make a call. Based on the successful result of the call I may decided to throw an error/reject and have it trickle down to the next call as an error. However if an error is thrown it just halt the process. How can I force the $http promise to reject without wrapping it in some $q code?
// A service
angular.module('app').factory('aService', function ($http, config) {
return {
subscribe: function (params) {
return $http({
url: '...'
method: 'JSONP'
}).then(function (res) {
// This is a successful http call but may be a failure as far as I am concerned so I want the calling code to treat it so.
if (res.data.result === 'error') throw new Error('Big Errror')
}, function (err) {
return err
})
}
}
})
// Controller
aService.subscribe({
'email': '...'
}).then(function (result) {
}, function (result) {
// I want this to be the Big Error message. How do I get here from the success call above?
})
In the above code I would like the Big Error message to end up as a rejected call. However in this case it just dies with the error. This is how I handle things in say Bluebird but it's a no go here.
Ti continue the Chain in a rejected state just return a rejected promise $q.reject('reason') from your $http result something like
$http.get(url).then(
function (response){
if(something){
return $q.reject('reason');
}
return response;
}
)
That way you'll get a a rejected promise and can react to it even when the api call is successful.
I have this app that uploads a file to a server using $cordovaFileTransfer and then sends data about the file to the same server. The file is transferred fine. The data is then sent to the server, and the server responds. But the response does not make it back to the promise callback. Why?
$scope.sendPost = function(data) {
//first upload a file then send more data about the file
$cordovaFileTransfer.upload('http://example.com', 'myfile.txt', options)
.then(function(result) {
var promise = MyFactory.sendFileData(data);
});
promise.then(function(response) {
//we never make it to here
});
}
and in MyFactory:
service.sendFileData = function(data) {
return $http({
//bunch of parameters. This function works, data is sent to the server and a response received
}).then(function(response) {
//this is fired when the response is received from the server. All is good so far.
return.response.data
});
}
return service;
$cordovaFileTransfer.upload returns a promise object, which you could use to build up promise chaining mechanism.
Code
$scope.sendPost = function(data) {
//get hold on `upload` function promise
var promise = $cordovaFileTransfer.upload('http://example.com', 'myfile.txt', options)
.then(function(result)) {
//return MyFactory.sendFileData promise here which will follow promise chaining
return MyFactory.sendFileData(data);
});
//promise.then will get call once `MyFactory.sendFileData` complete it
promise.then(function(response) {
//will get called once `sendFileData` complete its promise
});
}
its because you're relaying on another promise's callback to initiate a the promise and.. most probably before the promise gets initialized you are attaching a callback tot it.. so at the time of you attaching the callback, the promise is not yet initialized i.e. promise is null.. so in your console you'll see an error..
try doing some thing like
var x = function(response) {
//we'll make it to here now...
}
$cordovaFileTransfer.upload('http://example.com', 'myfile.txt', options)
.then(function(result)) {
var promise = MyFactory.sendFileData(data);
promise.then(x);
});
You should follow #PankajParkar solution though it's a better approach...
$scope.sendPost = function(data) {
//first upload a file then send more data about the file
$cordovaFileTransfer.upload('http://example.com', 'myfile.txt', options)
.then(function(result)) {
return MyFactory.sendFileData(result.data);
})
.then(function(response) {
});