This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
In AngularJS v1.6.9 I use HTTP post method for calling my API but $$state give me null so I am not able to give my list. I try to debug result = response.data give me to list but when that API Call service but post API function return also the list but in a controller, I enable to fetch that data.Please help me with that
Module is
var adminDashbord = angular
.module('mymodel', ['ui.router', 'ui.bootstrap', 'datatables', 'datatables.buttons']);
My API Call Service is
mymodel.service('ApiCall', ['$http', function ($http) {
var result;
var retResult;
var data;
this.PostApiCall = function (controller, method, jData) {
jData = JSON.stringify(jData);
result = $http.post('http://localhost:2153/' + controller + '/' + method, jData).then(function onSuccess(response)
{
result = response.data;
})
.catch(function onError(response)
{
console.error("CustomError:" + response.data);
console.error("Status:" + response.status);
});
return result;
};
Post API in a controller like
mymodel.controller('productmasterController', ['$scope', 'ApiCall',
function ($scope, ApiCall) {
$scope.init = function ()
{
$scope.getAllproduct();
}
$scope.getAllproduct = function () {
var reqdata = null;
result = ApiCall.PostApiCall("Product", "SelectAllProduct", reqdata).then(function (response) {
$scope.getProduct = response.ProductList;
});
};
}]);
My issue was $$state give an empty result.
You have two options:
result = $http.post(url).then(function(response){
return response.data;
})
return result;
OR
return $http.post(url).then(function(response){
return response.data;
})
Either way you need to return an Http Promise, which $http.get request returns. If you want your promise contain any data, you also need to return the response inside it, hence the second return is used (for response.data).
Related
I have this array I am getting through the following method:
var url= *url defined here*;
$scope.ViewProfile = function () {
$http.get(url)
.success(function (response) {
$scope.ProfileList = response;
$scope.FavNumbers = $scope.ProfileList[0].FavNumbers;
})
.error(function () {
});
}
I am required to edit the Fav Numbers list on the UI. and post it back to another url through http post url method. What I am stuck is with the concept of asynchronous calls, due to which I am unable to retrieve the favorite numbers list to be available for editing. Please help!
I have tried a method of using promises as follows:
app.factory('myService', function($http) {
var myService = {
async: function(url) {
var promise = $http.get(url).then(function (response) {
console.log(response);
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return myService;
});
In my controller I am doing:
angular.module('JuryApp').controller('mycontroller', ['myService', function (myService) {
myService.async(url).then(function(d) {
$scope.data = d;
});
app.controller('MainCtrl', function( myService,$scope) {
// Call the async method and then do stuff with what is returned inside our own then function
myService.async().then(function(d) {
$scope.data = d;
});
});
But I keep getting the error 'd is not defined'. It keeps giving an error of some sort, where the debugger goes into an infinite loop or something.
You are overcomplicating it, I think. Async calls are actually pretty simple:
You're service:
app.factory("myService", ["$http", function($http) {
var MyService = {
getData: function(url) {
return $http.get(url); //$http returns a promise by default
}
};
return MyService;
})];
Your controller:
angular.module('JuryApp').controller('mycontroller', ['myService', function (myService) {
$scope.FavNumbers = [];
var url = "http://my.api.com/";
myService.getData(url).then(function(response) {
$scope.FavNumbers = response.data[0].FavNumbers;
});
}]);
That's all that you need to do.
This question already has answers here:
Is this a "Deferred Antipattern"?
(3 answers)
Closed 5 years ago.
I create $http service and using $q.
Here is my $http service:
function dashboardService($http, $log, $q, config) {
var service = {
getClientId: getClientIDByLayout,
};
return service;
function getClientIDByLayout(layoutId) {
var deferred = $q.defer();
return $http.get(config.baseUrl + "api/ClientLayoutMercator?layoutId=" + layoutId).then(function (result) {
deferred.resolve(result.data);
}, function (result) {
deferred.reject(result);
});
return deferred.promise;
}
}
And here is how I call service above inside controller:
dashboardService.getClientId(layoutId).then(function (data) {
var t = data;//undifined
});
But result I get in this row var t = data is undefined.
Any idea why I get undefined from the service?
Basically you have two return statement inside your getClientIDByLayout function and both are returning promise itself. As I can see with your current implementation your're creating new promise & managing rejection / resolve manually. But the problem is the 1st return statement (return $http.get() is making other return statement(return deferred.promise) redundant. Hence 1st promise returned to subscription from controller. Eventually $http.get doesn't return anything so you get undefined in successCallback of then.
You can easily fix this issue by removing 1st return statement as shown below.
function getClientIDByLayout(layoutId) {
var deferred = $q.defer();
//removed `return` from below code.
$http.get(config.baseUrl + "api/ClientLayoutMercator?layoutId=" + layoutId).then(function (result) {
deferred.resolve(result.data);
}, function (result) {
deferred.reject(result);
});
//custom promise should get return
return deferred.promise;
}
Ideally creating promise overhead considered as antipattern, rather you can utilize the promise returned by $http.get. Just return a data from its success callback to chain the promise.
Code
function getClientIDByLayout(layoutId) {
̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶
return $http.get(config.baseUrl + "api/ClientLayoutMercator?layoutId=" + layoutId)
.then(function (result) {
//returning data from promise, it will provide it to subsequent `.then`
return result.data;
}, function (error) {
͟r͟e͟t͟u͟r͟n͟ $q.reject(error);
}
);
}
Instead of using $q.defer, simply return or throw to the handler functions in the .then method:
function dashboardService($http, $log, ̶$̶q̶,̶ config) {
var service = {
getClientId: getClientIDByLayout,
};
return service;
function getClientIDByLayout(layoutId) {
̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶
return $http.get(config.baseUrl + "api/ClientLayoutMercator?layoutId=" + layoutId).then(function (result) {
̶d̶e̶f̶e̶r̶r̶e̶d̶.̶r̶e̶s̶o̶l̶v̶e̶(̶r̶e̶s̶u̶l̶t̶.̶d̶a̶t̶a̶)̶;̶
return result.data;
}, function (result) {
̶d̶e̶f̶e̶r̶r̶e̶d̶.̶r̶e̶j̶e̶c̶t̶(̶r̶e̶s̶u̶l̶t̶)̶;̶
throw result;
});
̶r̶e̶t̶u̶r̶n̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶p̶r̶o̶m̶i̶s̶e̶;̶
}
}
The .then method returns a new promise which is resolved or rejected via the return value of the successCallback or errorCallback (unless that value is a promise, in which case it is resolved with the value which is resolved in that promise using promise chaining).1
By erroneously returning a promise with a then method that contained functions that lacked return or throw statements the service was returning a promise that resolved as undefined.
For more information, see You're Missing the Point of Promises.
I have create a service in service.js file in which I am using $http to get the list of posts. Here is the code of service.js.
app.service('PostService', function ($http, $log) {
var post =[];
var err = "";
$http({
method : 'GET',
url : 'http://myblog.local/wp-json/wp/v2/posts'
})
.then(function(response){
post = response.data;
}, function(reason){
err = reason.data.message;
});
this.getPost = function () {
return post;
};
this.getError = function () {
return err;
};});
And here it is my controller where I am using the service:
app.controller('BlogController', function($scope, $log, PostService){
$scope.postModel = PostService.getPost();
$scope.errorMessage = PostService.getError();
});
Everytime when I call getPost and getError method, it gives me nothing. Though $http is successfully getting response from the url. Why then method is not setting up the variable post and err.
You are using incorrect pattern of calling server. Http call is async action, so it takes some time to execute the code while running getPost() is a simple function which returns value just after you call it even if the value is still empty. So what you need to do here is to return Http call and assign it to needed model, just after it returns value.
app.service('PostService', function ($http, $log) {
var post =[];
var err = "";
this.getPost = function () {
return $http({
method : 'GET',
url : 'http://myblog.local/wp-json/wp/v2/posts'
})
.then(function(response){
return response.data;
}, function(error){
return error;
});
};
});
app.controller('BlogController', function($scope, $log, PostService){
PostService.getPost().then(function(post){
// here you can put logic to check is post an data or error
$scope.postModel = post;
});
});
I am currently trying to store a $http JSON request to a variable in a factory and then retrieve the value of that variable in a controller.
Currently all I receive back is undefined. I imagine the AJAX request isn't finished running before the function gets called. I am new to Angular so trying to grab any basic concepts I can and helpful knowledge.
app.factory('typiCode', function($http) {
var jsonService = {
async: function() {
var promise = $http.get('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
console.log(response);
return response.data;
})
return promise;
}
};
return jsonService;
});
app.controller("getJson", function($scope, typiCode) {
$scope.returnedData = typiCode.jsonService;
$scope.logResults = function() {
var theData = $scope.returnedData;
console.log(theData);
}
});
<button ng-click="logResults()">Launch data</button>
Thank you in advance!
Your typiCode factory returns your jsonService object. So you should be calling typiCode.async() somewhere in your code.
You could do, for example, like this in your controller:
app.controller("getJson", function($scope, typiCode) {
typiCode.async()
.then(function(data) {
$scope.returnedData = data;
})
$scope.logResults = function() {
var theData = $scope.returnedData;
console.log(theData);
}
});
var newservices = angular.module('newservices', []);
newservices.service('newservice', function ($http) {
return{
newdata: function(parameter){
return $http.get('/devicedetails/'+parameter).success(function(data) {
console.log(data)
return data
});
},
}
});
The above service is included in one of my controllers
data=newService.newdata($scope.dummy)
console.log(data)
while trying to print data what i get is $http function object as shown below
Object {then: function, catch: function, finally: function, success: function, error: function}
why is this so??
What you see is not an error. It's a Promise.
You did an $http GET request, which is asynchronous. $http.getreturns a promise that will be resolved when the remote request is completed. In that moment, you'll get the final value.
See this example, where getShops would be your method newData
this.getShop = function (id, lang) {
var promise = $http.get(appRoot + 'model/shops_' + lang + '.json');
return promise;
};
In a controller you can use it like this:
Shops.getShop($routeParams.id).then(function (response) {
console.log("data is", response.data);
$scope.shop = response.data[$routeParams.id];
});
When the data is ready, assign it to a scope.
In your case:
var data;
newService.newdata($scope.dummy).then(function (response) {
data = response.data;
});
Your service is returnig a promise
You should use some what like this, not tested though it should work.
data = newService.newdata($scope.dummy).then(function (response) {
return response.data;
},
function (error) {
return error;
});
You are using it wrong.
This work in promises. so in you controller you need to consume the promisses.
newService.newData($scope.dummy)
.then(function (data){
$scope.data = data;
console.log(data);
});
Try this.