Angular factory ajax call on every route change - javascript

I have a factory where I have a function getExpenseList which does an ajax call which queries the expense table and gives me the result.
Now I have two routes, 1 which is listing of expenses which is pushing the expense through the above function and the second route is an add. When I do a route change and come back to the listing page, the ajax call is made again. Ideally I should be able to store the expense object on the first ajax call and then reference the same object till someone is manually refreshing the browser.
please help me on this. Here is my factory code. Ideally I would like to refer to this.expenses if the data is present.
admin.factory('expenseFact', ['$http', function($http) {
var expense = {};
this.expenses = "";
expense.getExpenseList = function() {
this.expenses = $http({
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: "GET",
url: base_url + "rest/expenses"
});
return this.expenses;
};
return expense;
}]);
And here is my controller code
admin.controller('expenseLandCtrl', function ($scope,$rootScope,expenseFact) {
$scope.pageTitle = $rootScope.pageTitle;
expenseFact.getExpenseList().then(function (data) {
$scope.expenses = data.data;
});
});
admin.controller('expenseAddCtrl', function ($scope,$rootScope,expenseFact) {
$scope.pageTitle = $rootScope.pageTitle;
});

your factory will be like this
admin.factory('expenseFact', ['$http', function($http) {
return {
getExpenseList: function() {
var expense = {};
this.expenses = $http({
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: "GET",
url: base_url + "rest/expenses"
});
return this.expenses;
}
}
}]);
and you can call it from controller same way and it wont call it automatically.
btw i recommend use of promises.
below is same code with use of promise
admin.factory('expenseFact', ['$http', '$q'. function($http, $q) {
return {
getExpenseList: function(){
var deferred = $q.defer();
$http({method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).
then(function(response) {
deferred.resolve(response.data);
}, function(response) {
deferred.reject(response.status)
});
return deferred.promise;
}
}
}]);

You need to get the expenses once when the factory is loaded for the first time;
admin.factory('expenseFact', ['$http', function($http) {
var expenses = null;
$http({
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: "GET",
url: base_url + "rest/expenses"
}).success(function (exp) {
expenses = exp;
}); // get the expenses when the factory is loaded
return {expenses: expenses};
}]);
What this does is that it makes the expenses return from the factory refer to the one-time ajax call to get the expenses.

Related

How to call php file via factory/service method using Angular.js

I need to call php file using service/Factory method using Angular.js. Here instead of calling $http repeatedly in each file to call diferent php file for different purpose, I need to make it common. I am explaining one example below.
logincontroller.js:
var loginAdmin=angular.module('Takeme');
loginAdmin.controller('loginController',function($scope,$http,$location,$window,inputField){
$http({
method: 'POST',
url: "php/Login/verify.php",
data: userData,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(function successCallback(response){
},function errorCallback(response) {
});
}
I have one common route.js file which is common for all controller and given below.
route.js:
var Admin=angular.module('Takeme',['ui.router', '720kb.datepicker','ngMessages','ngCapsLock','ui.bootstrap','ngFileUpload','angularUtils.directives.dirPagination']);
Admin.run(function($rootScope, $state) {
$rootScope.$state = $state;
});
Admin.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('/',{
url: '/',
templateUrl: 'view/login.html',
controller: 'loginController'
})
})
Admin.factory('inputField',function($timeout,$window){
return{
borderColor:function(id){
$timeout(function() {
var element = $window.document.getElementById(id);
if(element){
element.focus();
element.style.borderColor = "red";
}
});
},
clearBorderColor:function(id){
$timeout(function() {
var element = $window.document.getElementById(id);
if(element){
element.style.borderColor = "#cccccc";
}
});
}
};
});
Here I need to that $http service to call the php file common for which in every controller I will call that $http repeatedly. I need to pass only the parameters for $http service and return the response.
create a factory/service
angular.module('myApp').factory('DataService', DataService);
DataService.$inject = ['$http', '$q'];
function DataService($http, $q) {
return {
getData: getData,
}
function getData(userData) {
var deferred = $q.defer();
$http({
method: 'POST',
url: "php/Login/verify.php",
data: userData,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(function(response) {
deferred.resolve(response.data);
},
function(error) {
deferred.reject(error.data);
});
return deferred.promise;
};
}
then use this factory whenever you need in a controller
angular.module('myApp')
.controller('MyController', ['$scope', 'DataService',
function($scope, DataService ) {
$scope.getMyData = function() {
var data = {};
DataService.getData(data)
.then(function(response) {
}, function(error) {
});
};
}
]);

angular: passing data to $resource service

Hi there I write a service of $resource for connecting the api.
here is the code in service.js
.factory('selfApi2', function ($resource, localStorageService) {
var AB = {
data: function (apiURL, header, data, params) {
return $resource("http://localhost:4000/api" + apiURL, null, {
update: {
method: 'POST',
headers: header,
data: data,
params: params
}
});
}
};
return AB;
})
in my controller.js
var header = {
'Content-Type': 'application/x-www-form-urlencoded'
};
var myData = {
'phone': '12345678'
};
selfApi2.data('/tableName',header,{where:{"name":"kevin"}).update(myData, function(result){
console.log("update Kevin's phone succeed",result);
})
it works. But why the variable myData should put inside the update() part rather than the data() part?
In your case, the data() is a function which will just create a ReST resource which would expose rest apis get save query remove delete as default.
So in this data() call you are just creating the rest resources. Passing myData with this function would not make any sense. The data() call would return the Resource instance which will have your update api function which accepts the parameters.
And, passing your data at api construction time does not make sense.
Here is the complete reference
I think it's because "data" is a function that returns object of $resource.
Try the scenario below:
// service
.factory('api', function ($resource) {
var api = {};
api.issues = $resource("http://localhost:4000/api/issues");
api.users = $resource("http://localhost:4000/api/users", {}, {
update: {
method: 'PUT',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
},
});
return api;
})
// controller
api.users
.update({where:{name:'kevin'}})
.$promise.then(function(success) {
// DO SOMETHING
});
...
api.issues.query().$promise.then(
function(success) {
// DO SOMETHING
});

Angular $scope is setting value first than service, after second function call everything fine

I'm trying to set data to controller using my service viewShare, when i look to my console i can see the console.log of controller coming first and undefined but the services started first the strange is after this console.log, i can see the console.log from viewShare populated. If i try the function in controller again then my controller is populated correctly.
my controller:
$scope.getLine = function(search){
arcTouchAPI.getLine(search);
console.log(viewShare.getDetails);
$scope.details = viewShare.getDetails.details; //angular ignores my viewShare call and go to console.log($scope.details) than it start the viewShare service
$scope.$apply;
console.log($scope.details);
};
my service API:
var _getLine = function(search){
var encoded = $base64.encode("xxxx:xxxx");
$http({
url: "https://api.appglu.com/v1/queries/findRoutesByStopName/run",
headers : {
"X-AppGlu-Environment":"xxxx",
"Authorization": "Basic "+encoded,
"Content-Type" : "application/json; charset=utf-8"
},
method: 'POST',
data: {
"params":{
"stopName": "%"+search+"%"
}
}
}).then(function(response){
viewShare.add(response.data.rows);
// console.log($rootScope.details + "details");
console.log(response.data.rows);
});
}
return {
getLine : _getLine
}
});
my service to share data between views:
angular.module('myApp').factory('viewShare', function viewShare() {
var messages={};
var _add = function(message){
messages.details = "";
messages.details=message;
console.log(messages.details);
return messages.details;
};
var _getDetails = function(){
return messages;
};
return{
getDetails: messages,
add: _add
}
});
$http call is non-blocking, which means that your console.log is executed straight after your request is sent to getLine (as coded), however this does not wait for the $http call to finish, and therefore has no data right away. You should return the $http promise from _getLine, and wait for the promise to resolve, before trying to getDetails. Furthermore, an explicit call to $scope.$apply is not necessary.
var _getLine = function(search){
var encoded = $base64.encode("xxxx:xxxx");
return $http({ // add return statement here to return a promise
url: "https://api.appglu.com/v1/queries/findRoutesByStopName/run",
headers : {
"X-AppGlu-Environment":"xxxx",
"Authorization": "Basic "+encoded,
"Content-Type" : "application/json; charset=utf-8"
},
method: 'POST',
data: {
"params":{
"stopName": "%"+search+"%"
}
}
}).then(function(response){
viewShare.add(response.data.rows);
// console.log($rootScope.details + "details");
console.log(response.data.rows);
});
}
Change controller to:
$scope.getLine = function(search){
arcTouchAPI.getLine(search).then(function(){
console.log(viewShare.getDetails);
$scope.details = viewShare.getDetails.details;
});
};

Angular async http request

I am trying to do a http ququest in angular. Somehow it seems am missing out on something which i cannot figure out what it is?
On Page load i get this error:
Error: [$injector:undef] http://errors.angularjs.org/1.4.5/$injector/undef?p0=%24formServices
My Service:
app.factory('$formServices',['$http','$q',function ($http, $q) {
function postSubmit (fData) {
return $http({
url: 'forms/Form1.php',
method: "POST",
data: { items: JSON.stringify(fData) }
});
}
}
]
);
And the controller that calls the service:
$formServices.postSubmit($scope.Parameters).then(function (response) {
console.log(response);
$scope.Results = response;
});
What am i missing out on?
$injector:undef
Try adding a return to your factory. Also, if you wish to call the function with dot notation you need to place the function inside of an object.
app.factory('$formServices',['$http','$q',function ($http, $q) {
return {
postSubmit: function(fData) {
return $http({
url: 'forms/Form1.php',
method: "POST",
data: { items: JSON.stringify(fData) }
});
}
}
}
]
);
Factory must return object from factory, so that will be exposed via to factory consumer via injecting its dependency.
Code
app.factory('$formServices', ['$http', '$q', function($http, $q) {
function postSubmit(fData) {
return $http({
url: 'forms/Form1.php',
method: "POST",
data: {
items: JSON.stringify(fData)
}
});
}
// should object
return {
postSubmit: postSubmit //link post submit to function
}
}]);
The issue is that your factory does not return an object. To learn more about this I suggest reading https://docs.angularjs.org/guide/providers
Evilzebra's answer would work I believe, but if you ever wanted to have more functionality in your factory, a good way to structure factories is:
app.factory('$formServices',['$http','$q',function ($http, $q) {
var service = {};
service.postSubmit = function (fData) {
return $http({
url: 'forms/Form1.php',
method: "POST",
data: { items: JSON.stringify(fData) }
});
}
return service;
}]);
This would allow you to add more features, appending them to the service object.

Use parameters in angular factory for custom header

I'm trying to find a way to pass a parameter so I can use it in my 'endpoint' variable, as you can see in my code I have the url and in the end of it I have "/clientes", but, in my API I also have "products" and "travels", so I'm looking for a solution to use a variable so I can change the end of the url, otherwise I'll have to create another factories just to get my "products" and my "travels".
angular.module('starter.services', [])
.factory('ServiceClientes', ['$http', function ($http) {
var endpoint = 'http://api.rep.com/api/clientes';
var token = '99KI9Gj68CgCf70deM22Ka64chef2J2J0G9JkD0bDAcbFfd19MfacGf3FFm8CM1hG0eDiIk8';
var credencial = 'rm#w.com:cd8cdx5ef753a06ee79fc75dc7cfe66c';
var origem = 'mobile';
var config = {
url: endpoint,
dataType: 'json',
method: 'GET',
data: '',
headers: {
'X-API-TOKEN': token,
'X-API-CREDENCIAL': credencial,
'X-API-ORIGEM': origem,
"Content-Type": "application/json"
}
};
return {
getAll: function () {
return $http(config);
}
};
}]);
controller:
.controller('PlaylistsCtrl', function ($scope, ServiceClientes) {
ServiceClientes.getAll().success(function (data) {
$scope.playlists = data.dados;
}).error(function (error) {
console.log(error);
});
})
Then make your function injectable with a parameter:
var endpoint = 'http://api.rep.com/api/';
var config = {
dataType: 'json',
method: 'GET',
data: '',
headers: {
'X-API-TOKEN': token,
'X-API-CREDENCIAL': credencial,
'X-API-ORIGEM': origem,
"Content-Type": "application/json"
}
};
return {
getAll: function (url) {
config.url = endpoint + url;
return $http(config);
}
};
controller:
ServiceClientes.getAll("clientes").success(function (data) {

Categories