In angularJS, How to refactor an $http call into a Service? - angularjs

I tried to put the below code into a service but I seem to be missing something! I have to click the button twice to update the list shown in the table:
$scope.todoList = [];
$scope.showTodoList = function(){
var url = '/api/v1/todo/list/'+$scope.report.from+'/'+$scope.report.to;
$http({
method: 'GET',
url: url
}).then(function successCallback(response) {
$scope.todoList = response.data;
}, function errorCallback(response) {
console.log(response);
});
}
So I tried to do this:
angular.module('ReportController', []).controller('ReportController', ['$scope', '$http', '$rootScope', '$location', '$localStorage', '$routeParams', 'Report', 'Todo',
function ($scope, $http, $location, $localStorage, $routeParams, Report, Todo) {
$scope.todoList = [];
$scope.showTodoList = function(){
$scope.todoList = Report.getList($scope.report.from, $scope.report.to);
}
}]);
then i created a module and added the factory there and loaded this module with all others
angular.module('ReportService', []).factory('Report', ['$q', '$filter', '$http', '$timeout', function ($q, $filter, $http, $timeout) {
var list;
function getList(date_from, date_to){
var url = '/api/v1/todo/list/'+date_from+'/'+date_to;
$http({
method: 'GET',
url: url
}).then(function successCallback(response) {
list = response.data;
}, function errorCallback(response) {
console.log(response);
});
return list;
}
return {
getList: getList
};
}]);

Your problem seems to be that you are not waiting for the callback of $http call when returning the list.
You should make the ReportService's getList function to return a callback or a Promise. It will also change a bit how you need to handle the function call in your ReportController.
Example how to do this with callbacks:
ReportService:
angular.module('ReportService', []).factory('Report', ['$q', '$filter', '$http', '$timeout', function ($q, $filter, $http, $timeout) {
var list;
function getList(date_from, date_to, callback){
var url = '/api/v1/todo/list/'+date_from+'/'+date_to;
$http({
method: 'GET',
url: url
}).then(function successCallback(response) {
list = response.data;
return callback(list);
}, function errorCallback(response) {
console.log(response);
return callback(null);
});
}
return {
getList: getList
};
}]);
ReportController:
angular.module('ReportController', []).controller('ReportController', ['$scope', '$http', '$rootScope', '$location', '$localStorage', '$routeParams', 'Report', 'Todo',
function ($scope, $http, $location, $localStorage, $routeParams, Report, Todo) {
$scope.todoList = [];
$scope.showTodoList = function(){
Report.getList($scope.report.from, $scope.report.to, function(res){
if(res) {
$scope.todoList = res;
}
});
}
}]);

Related

Why angularjs's constant not working with factory

I have constant mainApp.constant('baseUrl', 'http://localhost:63760') , i need to use it as default base url for all of my factory. when I inject it to a controller, it's working perfectly, but not working with factory(when factory called by the controller) giving an undefined error. please see my below codes.
app.js
'use strict';
var mainApp = angular.module("mainApp", ["ui.router", "ui.bootstrap"]);
mainApp.constant('baseUrl', 'http://localhost:63760');
factory
mainApp.factory('StudentServices', ['$http', '$rootScope', function ($http, $rootScope, baseUrl) {
return {
GetStudentProfileByPIN: function (param) {
alert(baseUrl);
return $http({
url: baseUrl + '/Api/ApiProfile/GetStudentProfile/' + param,
method: 'POST',
async: false
});
}
};
}]);
controller
mainApp.controller('loginController', function ($scope, $rootScope, $state, $window, StudentServices) {
$scope.user = {};
$scope.login = function () {
StudentServices.GetStudentProfileByPIN($scope.PIN).then(function (response) {
if (response.data.Student != null) {
$window.localStorage.setItem('Student', angular.toJson(response.data));
$window.location.href = "/Profile/#/home";
}
else {
alert(response.data.Message);
}
});
};
});
You are missing **'baseUrl',**You should have it as,
mainApp.factory('StudentServices', ['$http', '$rootScope','baseUrl', function ($http, $rootScope, baseUrl) {
inject the string baseUrl too
mainApp.factory('StudentServices', ['$http', '$rootScope','baseUrl' function ($http, $rootScope, baseUrl)

call a soap webservice from ionic

i'm trying to call a soap webservice using this method : http://mcgivery.com/soap-web-services-angular-ionic/ however my screen only shows a blank page instead of the login screen. what could be the probleim?
here's my services.js code:
.factory('loginService', ['$soap', function($soap){
var base_url = 'http://localhost/UserService3/WebService1.asmx';
return {
GetUser: function(uname){
return $soap.post(base_url,"getUserbyUsername", {Username: uname});
}
};
}])
and here's my controller.js code:
.controller('loginCtrl', ['$scope', '$stateParams', '$location', '$state', 'sharedProperties2','ConnectivityMonitor', '$ionicLoading', 'loginService',
function ($scope, $stateParams, $location, $state, sharedProperties2,
ConnectivityMonitor, $ionicLoading, loginService) {
$scope.show = function() {
$ionicLoading.show({
template: '<ion-spinner icon="android"></ion-spinner>',
showBackdrop: false
});
};
$scope.hide = function(){
$ionicLoading.hide();
};
$scope.userdata = {}
$scope.enterlogin = function(usern,pass)
{
userFactory.GetUser(usern).then(function(response) {
alert('get = ' + JSON.stringify(response.data));
})
}
}])
apparently it could not see the previous location of the added scripts angular.soap.js and soapclient.js, so i put the 2 files inside a folder named angular-soap inside the lib folder.

Make the browser wait for api response / http call response in angularjs

I tried the $q service as follows but the browser still not waiting for the response. I already spent almost a day to figure out a solution, I also tried the $timeout.
login.controller("loginCtrl", ['$scope', '$rootScope', '$filter', '$window', '$http', 'APIService', 'localStorageService', 'doAlert', '$translate', '$q', '$timeout',
function ($scope, $rootScope, $filter, $window, $http, APIService, localStorageService, doAlert, $translate, $q, $timeout) {
$scope.isLogOut = true;
$(window).unload(function () {
$rootScope.$broadcast('onUnload');
});
$scope.$on('onUnload', function (e) {
var deferred = $q.defer();
$http.get(url).
success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
});
Here is a sample where I use a callback to process data back from my utility
function get(url, callback, obj) {
$http.get(url, obj)
.then(function (response) {
callback(response.data);
}, function () {
notification.error(PLEASE_CONTACT_SYS_ADMIN);
});
}

Can't find out why i'm getting an injector error

I am getting an error on injecting my collections factory, but can't figure out where I went wrong:
Error: [$injector:unpr] http://errors.angularjs.org/1.3.0/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope%20%3C-%20collections
'use strict';
var thangular = angular.module('thangular', ['ngAnimate']);
thangular.config(function ($interpolateProvider,$httpProvider) {
$interpolateProvider.startSymbol('[[').endSymbol(']]');
$httpProvider.defaults.useXDomain = true;
});
thangular.factory('collections', ['$scope', '$http', '$q',
function ($scope, $http, $q) {
return {
all: function () {
var deferred = $q.defer();
var request = $http({
method: 'GET',
url: '/collections.json',
});
request
.success(function (result) {
deferred.resolve(result.content);
})
.error(function (error) {
deferred.reject(error);
});
return deferred.promise;
}
};
}
]);
thangular.controller('mainCtrl', ['$scope', 'collections',
function ($scope, collections) {
collections.all().then(function (data) {
console.log(data);
});
}
]);
I suppose you shouldn't inject $scope in factory declaration. Just change
thangular.factory('collections', ['$scope', '$http', '$q',
to
thangular.factory('collections', ['$http', '$q',
Factory declaration should not dependent upon controllers $scope.

Can't seem to be able to pass data from one controller to another

The issue is that I can't seem to send information from Controller 1 to Controller 2... I have my service that sets/gets data but it isn't working. The actual error that I'm getting is that Controller 1's dataService.getData is not a function... when it works elsewhere.
Service 1 (in its own file)
app.service('dataService', function() {
var data, queried;
return {
setData: function(queryData) {
this.data = queryData;
this.queried = false;
},
getData: function() {
this.queried = true;
return this.data;
}
};
});
Controller 1 (sending information)
app.controller('MyCtrl', ['$scope', '$location', '$state', function($scope, $location, $state, dataService) {
anotherService.functionName(function(err, data) {
// do some things here
actualService.doesntWork(function(err, data) {
if (!err) {
var query = {};
query.someField = data.someField;
dataService.setData(query);
$state.go("go.somewhere.else");
}
});
});
}]);
Controller 2 (getting information)
app.controller('MyCtrl2', ['$scope', '$location', '$state', function($scope, $location, $state, dataService) {
$scope.buttonPressed = function() {
console.log(dataService.getData());
}
}]);
You didn't injected service dataService inside your MyCtrl & MyCtrl2, ensure dependency should be injected before using it.
Controller
app.controller('MyCtrl', ['$scope', '$location', '$state','dataService', //<-added dependency here
function($scope, $location, $state, dataService) {
anotherService.functionName(function(err, data) {
// do some things here
actualService.doesntWork(function(err, data) {
if (!err) {
var query = {};
query.someField = data.someField;
dataService.setData(query);
$state.go("go.somewhere.else");
}
});
});
}]);
Controller2
app.controller('MyCtrl2', ['$scope', '$location', '$state','dataService',//<-added dependency here
function($scope, $location, $state, dataService) {
$scope.buttonPressed = function() {
console.log(dataService.getData());
}
}]);

Resources