Stop an interval of a controller on navigating to another site - angularjs

In my application I am constantly updating displayed data which changes on the server using an interval, which loads whenever the controller loads. The controller loads together with the function in the interval when I navigate to a specific site and I would like it to stop when I navigate to another. The problem is that after some time of usage of the site, I end up with a bunch of intervals running and it just appears nasty. Here is the code of the controller:
angular
.module('myApp')
.controller('TaxiesController', ['$scope', '$location', '$routeParams', '$route', 'dataFactory', '$interval', function ($scope, $location, $routeParams, $route, dataFactory, $interval) {
console.log('TaxiesController loaded')
var cancel = {
name: 'Preklic',
price: 500
}
$scope.taxies = [];
$scope.taxi = {};
$scope.taxi.history = [];
taxi = {}
taxi.history = [];
$scope.getTaxies = () => {
dataFactory.getTaxies().then(function (response) {
$scope.taxies = response.data;
});
}
$scope.getTaxi = () => {
var id = $routeParams.id;
dataFactory.getTaxi(id).then(function (response) {
$scope.taxi = response.data;
});
}
$scope.removeTaxi = (id) => {
dataFactory.removeTaxi(id).then(function (response) {});
}
$scope.getTotal = (taxi) => {
var total = 0;
for (var i = 0; i < taxi.history.length; i++) {
var rent = taxi.history[i];
if (rent.price) total += rent.price;
}
return total;
}
$scope.disableTaxi = (taxi, id) => {
taxi.drivable = false;
dataFactory.updateTaxi(id, taxi).then(function (response) {
$scope.taxi = response.data;
$route.reload();
})
}
$scope.cancelTaxi = (taxi, id) => {
console.log('cancelling..')
taxi.available = true;
taxi.history.unshift(cancel);
dataFactory.updateTaxi(id, taxi).then(function (response) {});
}
var updateTaxies = () => {
console.log('Checking rent length')
dataFactory.getTaxies().then(function (response) {
$scope.taxies = response.data;
});
}
$interval(updateTaxies, 2000);
}]);

Just add this inside the controller:
var intervalListener = $interval(updateTaxies, 2000);
$scope.$on('$destroy', function() {
$interval.cancel(intervalListener);
});
$destroy is an event that will be fired when a scope is being destroyed. Here is the doc about it

Related

Angular.js Call $http.get every second

How can I call $http.get every second to update my page?
var app = angular.module("CompanionApp", []);
app.controller('LoginController', function ($scope, $http) {
$scope.LoginSubmit = function() {
$http.get('/api/player/' + $scope.name)
.then(function(res) {
$scope.connected = res.data.connected;
$scope.health = res.data.health;
$scope.armour = res.data.armour;
})
};
});
Try $interval :
var app = angular.module("CompanionApp", []);
app.controller('LoginController', function ($scope, $http, $interval) {
var interval;
$scope.LoginSubmit = function() {
interval = $interval(function () {
$http.get('/api/player/' + $scope.name)
.then(function(res) {
$scope.connected = res.data.connected;
$scope.health = res.data.health;
$scope.armour = res.data.armour;
})
}, 1000);
};
$scope.stopCalls = function(){ // incase you want to stop the calls using some button click
$interval.cancel(interval);
}
});

Use data from factory in controller in angularjs

I am very new to AngularJS.
I want to pass an array data from my app factory to app controller.
Here is my app.factory code.
App.factory('buyFactory', ['$http', function($http) {
factory.Search = function(scope, d) {
var data = scope.search;
scope.CarsData = [];
all_cars = [];
scope.isLoading = true;
$http.post(ajaxurl + '?action=search_car', d)
.success(function(response) {
angular.forEach(response, function(c) {
c.price = parseFloat(c.price);
c.driven = parseFloat(c.driven);
c.year = parseFloat(c.year);
});
angular.forEach(response, function(value, key) {
all_cars.push(value);
scope.CarsData = all_cars;
scope.TotalItems = scope.CarsData.length;
scope.isLoading = false;
})
.error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
scope.isLoading = false;
});
}
return factory;
}]);
and this is app.controller as
App.controller('buyController', ['$scope', '$http', 'buyFactory', '$filter', function($scope, $http, buyFactory, $filter) {
$scope.CarsScroll = buyFactory.Search.CarsData();
$scope.loadMore = function() {
var last = $scope.CarsScroll[$scope.CarsScroll.length - 1];
for (var i = 1; i <= 3; i++) {
$scope.CarsScroll.push(last + i);
}
};
//scroll
}]);
I want to use output obtained from factory i.e. CarsData as a variable in my app controller. But I am not able to get it. I have tried using services also. Is there method to use array data in a simplest way.
Your syntax is completely broken, i would recommend following any course of AngularJS. As for how to correctly do what you are trying to would look something like this
app.factory('buyFactory', ['$http', '$q', function($http, $q) {
var factory = {
search: function(d) {
return $q(function(resolve, reject) {
$http.post(ajaxurl + '?action=search_car', d).then(function(response) {
angular.forEach(response, function(c) {
c.price = parseFloat(c.price);
c.driven = parseFloat(c.driven);
c.year = parseFloat(c.year);
});
var carsData = [];
angular.forEach(response, function(value, key) {
carsData.push(value);
})
var result = {
carsData: carsData,
total: carsData.length
}
resolve(result);
}, function(error) {
reject(error);
})
});
}
}
return factory;
}]);
app.controller('buyController', ['$scope', '$http', 'buyFactory', '$filter', function($scope, $http, buyFactory, $filter) {
buyFactory.search().then(function(result) {
var cars = result.carsData;
var total = result.total;
})
}]);
Note: i do not know what the d parameter is for neither why the angular.forEach statements so it might not be fully functional. But this is more as guideline for how your factory should look and be used.

Retrieving data from promise | Angularjs

I'm trying to add a top posted section on my dashboard. Getting the top 'captures' aka posts wasn't an issue, though working with Auth0, I need to link the user info with the corresponding users.
Currently I am getting a promise in my dataObj that I pass along to check who made the most votes, but seeing it's asynch I'm having issues retrieving the data and putting it into the users variable:
app.controller('dashboardCtrl', ['$scope', '$http', 'captureApi', 'userApi', 'filterFilter', '$q', function($scope, $http, captureApi, userApi, filterFilter, $q){
$scope.captures = [];
$scope.pageSize = 4;
$scope.currentPage = 1;
$scope.topPosters = [];
captureApi.getAllCaptures().then(function(res) {
$scope.captures = res.data;
userApi.getUsers().then(function(res){
$scope.getCount = function getCount(strCat){
return filterFilter( $scope.captures, {userId:strCat}).length;
};
var users = res.data.users;
var i;
for(i=0; i<users.length; i++) {
var userId = users[i].user_id;
console.log(userId);
console.log($scope.getCount(userId));
$scope.user = userApi.getUser(userId).then(function(res){
$scope.userInfo = res.data;
console.log($scope.userInfo);
return res.data;
});
var dataObj = {
user : $scope.user,
userId : userId,
amountPosted : $scope.getCount(userId)
};
$scope.topPosters.push(dataObj);
}
console.log($scope.topPosters[0].user);
});
});
}]);
As you can see, I get all the captures, then I count them depending on their userId.
Once this is done I add them to the dataObj.
But in between I'm trying to add the user information (using userApi.getUser(ID) and also add their information to this dataObj. At the moment I'm getting a promise. How do I convert this into the dataObj of each user.
Try to load all data before pushing to topPosters. An example:
app.controller('dashboardCtrl', ['$scope', '$http', 'captureApi', 'userApi', 'filterFilter', '$q', function ($scope, $http, captureApi, userApi, filterFilter, $q) {
$scope.captures = [];
$scope.pageSize = 4;
$scope.currentPage = 1;
$scope.topPosters = [];
$scope.getCount = function getCount(strCat) {
return filterFilter($scope.captures, {userId: strCat}).length;
};
$q.all({captures: getAllCaptures(), users: getUsers()}).then(function(collections) {
$scope.captures = collections.captures;
return collections.users;
}).then(function (users) {
return $q.all(users.map(function (user) {
return getUserById(user.userId);
}));
}).then(function (users) {
$scope.topPosters = users.map(function(user) {
//I think your user has propery "id" or similar
return {
user: user,
userId: user.id,
amountPosted: $scope.getCount(user.id)
}
});
console.log($scope.topPosters);
});
function getAllCaptures() {
return captureApi.getAllCaptures().then(function (res) {
return res.data;
});
}
function getUsers() {
return userApi.getUsers().then(function (res) {
return res.data.users;
});
}
function getUserById(userId) {
return userApi.getUser(userId).then(function (res) {
return res.data;
});
}
}]);

Using $http in a controller in AngularJS

I have an AngularJS 1.2 app. My app has a controller that looks like this:
myApp.controller('MyController', ['$scope', '$rootScope', '$http',
function ($scope, $rootScope, $http) {
$scope.newItem_Click = function () {
var modalInstance = $modal.open({
templateUrl: 'item-dialog.html',
size: 'md',
controller: function ($scope, $modalInstance) {
$scope.item = { typeId: 7, id: '-1' };
$scope.saveItem = function (did) {
if ($scope.item.description) {
if ($scope.item.description.trim().length > 0) {
$scope.item.departmentId = did;
$modalInstance.close($scope.item);
}
} else {
alert('Please enter your description.');
}
};
$scope.cancelItem = function () {
$modalInstance.dismiss('cancel');
};
$scope.getItems = function (departmentId) {
var url = '/api/items?departmentId=' + departmentId;
return $http.get(url).then(
function (response) {
var results = response.data;
results.reverse();
var items = [];
var i = 0;
angular.forEach(results, function (item, key) {
var local = results[i].CreatedUTC;
results[i].CreatedOn = new Date(local);
items.push(item);
i = i + 1;
});
console.log(items);
$scope.items = items;
}
);
};
$scope.$on('list-updated', function () {
$scope.getItems($scope.item.id);
});
}
});
modalInstance.result.then(
function (item) {
var apiUrl = '/api/items';
apiUrl = apiUrl + '?typeId=' + item.typeId;
if (item.departmentId!== '-1') {
apiUrl = apiUrl + '&departmentId=' + item.departmentId;
}
apiUrl = apiUrl + '&content=' + item.description;
apiUrl = encodeURI(apiUrl);
$http.post(apiUrl).then(
function () {
$rootScope.$broadcast('list-updated');
}
);
}
);
};
}]);
For some reason, I can successfully save an item. The console.log(items) statement displays all of the items as I would expect. However, my view is not being updated. What am I doing wrong? I suspect its because I'm assigning $scope.items inside of the HTTP response. Yet, I'm not sure how to get around it.
I know this is not recommended. However, I am in crunch mode.

Passing page number param for infinite-scroll to return more results from the backend

I'm using infinite-scroll and I want to request more data using $http. So next page / next 10 results etc.
This is my current working code (I put this in a factory as I read on another post somewhere that this was a good idea, I'm now thinking a service might be better but I'm not sure yet):
angular.module('hotels', [])
.factory('hotels', function($http) {
var hotels = {};
hotels.get = function(callback) {
$http.get('/php/hotels.php').success(function(data) {
callback(data);
});
};
return hotels;
});
angular.module('app', ['hotels', 'infinite-scroll'])
.controller('hotelsCtrl', function ($scope, hotels){
hotels.get(function (data) {
$scope.hotels = data.results;
})
});
How do I pass back a param page=3 and have the backend return more results?
I thought it might look something like this but its not working.:
angular.module('hotels', [])
.factory('hotels', function($http) {
var hotels = {};
hotels.get = function(callback) {
$http.get('/php/hotels.php?page='+$scope.page).success(function(data) {
callback(data);
});
};
return hotels;
});
angular.module('app', ['hotels', 'infinite-scroll'])
.controller('hotelsCtrl', function ($scope, hotels){
$scope.page = $scope.page + 1;
hotels.get({page: $scope.page}, function (data) {
$scope.hotels.push.apply($scope.hotels, data.results);
})
});
Any ideas?
This does the job:
angular.module('hotels', [])
.factory('hotels', function($http) {
var hotels = {};
hotels.get = function(params, callback) {
$http.get('/php/hotels.php', {params: {page: params.page}}).success(function(data) {
callback(data);
});
};
return hotels;
});
angular.module('app', ['hotels', 'infinite-scroll'])
.controller('hotelsCtrl', function ($scope, hotels){
$scope.page = 1;
$scope.addMoreItems = function() {
$scope.hotels=[];
hotels.get({page: $scope.page}, function (data) {
//$scope.hotels.push(data.results);
for (var i = 0; i < data.length; i++) {
$scope.hotels.push(data[i]);
}
$scope.page+=1;
})
}
});

Resources