angularjs: $interval call never happen after it's cancelled - angularjs

I've a requirement where as soon as i load a page it makes makes api call and
shows data on the page. and after every 15 sec it keeps loading the data an shows and i've a popup that has a click button function(ConfigModalButtonClick ). When i open the popup i wanted to stop the interval that makes the api call so for that i added $interval.cancel when popup is open but now when i click the button in popup the api call never happen. how can i make sure api call happens it looks like i need to call interval function again somewhere but not sure where??
the interval should run normally after 15 sec when i close the popup.
$scope.timeDelay = 15000;
$scope.loadData = function() {
$http.post(url,data
).then(
function(response) {
$scope.output = response.data;
},
function(response) {
$scope.retrieveErrorMssg = "Failed to retrieve required data. Try again.";
});
};
var interval = $interval(function() {
$scope.loadData();
}, $scope.timeDelay);
$scope.showConfigurationModal = function() {
$interval.cancel(interval);
$scope.state.settingModalVisible = true;
};
$scope.closeConfigurationModal = function() {
$scope.state.settingModalVisible = false;
// Need to explicitly trigger the dismiss function of the modal
$scope.settingModalDismiss();
};
$scope.ConfigModalButtonClick = function () {
$scope.state.settingModalVisible = false;
//some data manipulation
$scope.loadData();
};

Related

How could I show the loading popop before the fetching data and rendering task are done

I have a page which will call search_hotels method.
It should wait about 2 seconds for the Server returns the JSON.
And the size of the returned JSON contains 2 thounds items.
It also needs 2~3 seconds to process and render all items with ng-repeat.
What the better practice to show the loading window for telling people to wait?
function search_hotels(q_param) {
roomSkuService.search(q_param).$promise.then(function(resp) {
_.each(resp, function(item) {
var region = item.hotel.region;
if ($scope.region.list.indexOf(region) < 0) {
$scope.region.list.push(region)
}
});
$scope.hotels = _.groupBy(resp, function(row) {
return row.hotel_id;
});
});
}
I would recommend u use $timeout to hide the loading window after the rendering finishes.
function search_hotels(q_param) {
//show the loading window
roomSkuService.search(q_param).$promise.then(function(resp) {
_.each(resp, function(item) {
var region = item.hotel.region;
if ($scope.region.list.indexOf(region) < 0) {
$scope.region.list.push(region)
}
});
$scope.hotels = _.groupBy(resp, function(row) {
return row.hotel_id;
});
//execute after rendering
$timeout(function(){
//hide loading window
},0);
});
}

Angularjs chat with strange polling

I created a simple chat with the frontend in angularjs. It has on the left size a simple index, of all the conversations that user has, with a show(chat_id) action, that opens up on the right side the chat itself, using polling to fetch new messages.
The main piece of the controller that does the functionality described:
$scope.show = function(id) {
$scope.chat = [];
$scope.currentConversation = id;
var poll = function(){
conversation.get(id).then( function( conversation ) {
$scope.chat = conversation.data.messages;
$scope.form = true;
$timeout(function() {poll()}, 5000)
});
}
poll();
}
My problem, is whenever I click on two different conversations quickly, say show(1) and show(2) I get a weird behavior where it switches from conversation 1 to 2, back and forth, with the polling action.
Here is the get requests angular is making.
and for contextualization, here's the chat simple UI
As I said in the comment, every time show() is called, you start a new recursive loop that polls the conversation with the given id every 5 seconds.
So, if you click 4 conversations (1, 2, 3 and 4), you will end up with a refresh of conversation 1 every 5 seconds, another refresh of conversation 2 every 5 seconds, etc.
That's not what you want. Once you show a conversation, you only want to refresh that conversation, not the other ones.
So you could use that following code that cancels the previous timeout every time show() is called, and that verifies that the displayed conversation ID is the right one when getting a response:
var timer;
$scope.show = function(id) {
$scope.chat = [];
$scope.currentConversation = id;
if (timer) {
$timeout.cancel(timer);
}
var poll = function(){
conversation.get(id).then( function( conversation ) {
if ($scope.currentConversation == id) {
$scope.chat = conversation.data.messages;
$scope.form = true;
timer = $timeout(function() {poll()}, 5000);
}
});
}
poll();
}
You probably want to do a check inside your inner function to make sure that $scope.currentConversation === id. That'll prevent it from losing context. My guess is that it's a race condition that you're clicking before the first
conversation.get(id) comes back.
$scope.show = function(id) {
$scope.chat = [];
$scope.currentConversation = id;
var poll = function(){
conversation.get(id).then( function( conversation ) {
if ($scope.currentConversation !== id) return; // Prevent the race condition
$scope.chat = conversation.data.messages;
$scope.form = true;
$timeout(function() {poll()}, 5000)
});
}
poll();
}

How to call print function in new window after page is loaded?

Ok i have this button :
and i have this function for confirm ticket:
$scope.ConfirmTicketPayOut = function (ticketPin, username)
{
$scope.ticketPin = ticketPin;
localStorage.setItem("ticketPin", ticketPin);
accountDataProviderService.confirmTicketPayOut(ticketPin, username)
.then(function (response) {
$scope.confirmTicketPayOut = response;
if ($scope.confirmTicketPayOut.Result == true)
{
var w = $window.open('/account/ticketprint');
angular.element(w).bind('load', function () {
w.print();
});
}
});
}
I have problem because when user click on button i need to open new window with data and to call print option. In this case i get print option and new window is open but the page is blank so my conclusion is that page is loaded after print option is appeared. I need to load page and show print option at same time, but without $timeout. Is that possible?
Try using angular event viewContentLoaded. call your method after this event is fired.
Example
$scope.$on('$viewContentLoaded', function() {
// Your method call
}

showing progressbar while function fetching data from database

I have a button on this button click I am calling a function e.g
<button ng-Click=”getData()”></button>
<div class=”Progressbar” ng-show=” showProgress “></div>
controller:
$scope.showProgress = false;
$scope.getData = function () {
$scope.showProgress = !$scope.showProgress;
myRepository.getAllData();
}
This function is taking longer time to fetch data from Database.
I want to show a SPINNER while data is getting fetched.
But this “Div” is shown only after whole function has been completed.
I want it to be shown before the completion of function.
How I can achieve that?
Set showProgress = true before loading data, and to false once data is loaded. For reliable behavior make myRepository.getAllData return promise, and then use its then method to hide spinner:
$scope.getData = function() {
$scope.showProgress = true;
myRepository.getAllData().then(function() {
$scope.showProgress = false;
});
}

Poll server with a timer in angularjs

I am in a spot where I need to poll my server for data every so often. I have looked around at how people are handling this in angularjs and I am pretty confused.
Some examples are of just simple counters that increment up/down. Other are using the $timeout service. I need the ability to turn this on/off with a button click. I.E. click to start poll, poll every 30 seconds, click button to stop polling.
I am not claiming to be great at javascript nor angular so please go easy. I did write my own service that uses setInterval and clearInterval:
angular.module('myModule', [])
.factory('TimerService',
function () {
var timers = {};
var startTimer = function(name, interval, callback) {
// Stop the timer if its already running, no-op if not running
stopTimer(name);
timers[name] = setInterval(function() {
callback();
}, interval);
// Fire right away, interval will fire again in specified interval
callback();
}
var stopTimer = function(name) {
var timer = timers[name];
if (timer) {
clearInterval(timer);
delete timers[name];
}
}
return {
start: startTimer,
stop: stopTimer
};
});
Then in my controller I do this:
var timerARunning = false;
$scope.onClickA = function() {
var timerName = 'timerA';
timerARunning = !timerARunning;
if (timerARunning) {
TimerService.start(timerName, 5000, function() {
alert("Timer A just fired");
});
} else {
TimerService.stop(timerName);
}
}

Resources