Mithun Nath Mithun Nath - 3 months ago 23
HTTP Question

how to use $http in a service or factory with ionic framework

I'm trying to use the basic tabs template in ionic. Just wanted to use the $http inside a service and collect data from an API end point. It works when $http is used within a controller but it is not inside a service. This is the basic tabs template in ionic framework. I'm trying to build something on top of that just by changing the data source to my api endpoint.

//Service body starts

.service('Datas', function($http) {
$http.get('https://www.googleapis.com/api_url').then(function(response){
var datas = response.data.items;

return {
all: function() {
return datas;
},

get: function(dataId) {
for (var i = 0; i < data.length; i++) {
if (datas[i].id === parseInt(dataId)) {
return data[i];
}
}
return null;
}
};
});
//Service body ends


//controller starts here
.controller('Cntrl', function($scope, Datas) {

$scope.data = Datas.all();

})
//controller ends here


//template starts
<div ng-repeat="data in datas">
{{data.title}}

</div>

//template ends

Answer

The datas variable declaration should be in the service construction. Not enclosed in the success handler function.

app.service('Datas', function($http) {
    //Declare datas here
    var datas = [];

    $http.get(url).then(function(response){
        //NOT here
        //var datas = response.data.items;
        //Also use angular.copy
        angular.copy(response.data.items, datas);
    }); 

    return {
        all: function() {
            return datas;
        },
        get: function(dataId) {
            for (var i = 0; i < datas.length; i++) {
                if (datas[i].id === parseInt(dataId)) {
                    return datas[i];
                };
            };
            return null;
        }
    };
});

Also, since the controller fetches the datas object reference before the XHR completes, use angular.copy. Avoid using an assignment statement which would replace the original object reference with a new object reference.


Attaching $promise property

It might be wise to attach the httpPromise as a property to the datas object.

app.service('Datas', function($http) {
    //Declare datas here
    var datas = [];

    datas.$promise = $http.get(url).then(function(response){
        //NOT here
        //var datas = response.data.items;
        //Also use angular.copy
        angular.copy(response.data.items, datas);
        //return data for chaining
        return datas;
    });

The $promise property can come in handy when trying to avoid race conditions such as the controller using Datas.get before the XHR completes.

Comments