I can't reproduce this bug or figure out the cause of it: A user edits a form and submits, the changes are saved via PUT request, there is a GET request for data reload, but sometimes there is a second PUT request reverting the changes to the original values.
I've checked the logs and this second PUT request happens within seconds of the first PUT request. I have yet to reproduce this and the user says they did not edit a second time.
In the edit controller:
$scope.save = function() {
$scope.requestPending = true;
APIResources.userResource($route.current.userType,$route.current.params.id).update(makeUpdateObject()).$promise.then(function(data) {
$scope.userRefresh();
$scope.requestPending = false;
$rootScope.$broadcast('app.event.user.updated');
},
function(error){
console.log('Error saving', error);
});
$scope.$dismiss();
};
In the user controller:
$scope.userRefresh = function() {
APIResources.userResource($route.current.userType,$route.current.params.id).get().$promise.then(function(data) {
$scope.user = data;
// Time to reload the data is 2000ms to support 2G (450kbs) or higher
window.setTimeout(function() {
$rootScope.$broadcast('app.user.loaded', data, userType);
}, 2000);
}, function(err) {
console.log('Data failed to load.');
});
};
Related
My current ionic code able to get data then open the page. However, I want to open the page then only loading to get the data. I want to change the sequence since it takes 10s to load some data.
Here is my code:
$scope.openDetail = function (stock) {
console.log(stock.symbol);
$ionicLoading.show();
//stockCondition
if(stock.symbol.length<=$scope.stockCondition) {
$stockDataFactory.getStockDetails(stock).then(
function success(data) {
$globalFactory.personalStockData = data.details;
$globalFactory.personalStockNews = data.news;
$ionicLoading.hide();
$state.go("app.page1");
},
function error(error) {
alert(error.message);
console.error(error);
$ionicLoading.hide();
}
);
}
else{//WarrentCondition
$stockDataFactory.getWarrentDetails(stock).then(
function success(data) {
$globalFactory.personalStockData = data.details;
$globalFactory.personalStockNews = {};
$ionicLoading.hide();
$state.go("app.page1");
},
function error(error) {
alert("Stocks Not Found.");
console.error(error);
$ionicLoading.hide();
}
);
}
};//end
In order to open the $state.go("app.page1"); first, then only loading data, how shall I made changes of my code?
You should show the page1's html templet .
My approach will be using ng-if="personalStockData" with the $setTimeout() trick to show the data only when it's loaded. looks something like this
//page1 controller
$stockDataFactory.getStockDetails(stock).then(
function success(data) {
$setTimeout(function(){
$scope.personalStockData = data.details;
$scope.personalStockNews = data.news;
})
},
function error(error) {
alert(error.message);
console.error(error);
$ionicLoading.hide();
}
);
html
<div>
...
<div ng-if="personalStockData">
</div>
<div ng-if="personalStockNews">
</div>
...
</div>
anyways try not to use global variables, those are really hard to track.
You'll have to bring over the decision data that are explicit to the current page over to app.page1. For instance $scope.stockCondition. I suspect it is the same forstock.symbol. Will have to see what stock variable is.
There are many ways you can achieve this. Using query string is one option and is also the most conventional way. Some people prefer to store them in cookies, not efficient but applies to certain use-cases.
Again, I am not sure what $state is. Assuming it is angular-ui-router's statemanager. Then you can achieve this by;
$state.go("app.page1", {
stockCondition: $scope.stockCondition,
stocksymLen: stock.symbol.length
});
Then on app.page controller you can retrieve the values of the query string parameters by doing $state.params.stockCondition.
Once you have brought the decision variables across to the next page. The next step would be to plug them into the if-else statement you got from the other page onto app.page1.
Pseudo code:
angular.module('blah')
.controller('app.page1', function($scope, $state) {
// on page load
if($state.params.stocksymLen <= $state.params.stockCondition) {
// do your REST call
...
else {
...
}
});
I've read the docs but it's 3am and I'm at the end of me teather. Here's my controller:
controller('makeDashCtrl', function ($scope, $rootScope, $cookies, $location, $http, $interval) {
var userId = $cookies.get('user_id');
var orgId = $cookies.get('org_id');
$http.get('/api/consolidateProfile/').then(function(data){
console.log(data);
}, function(res){
console.log(res + " - Eh, consolidateProfile probably timed out, no biggie")
})
var testStart = $interval(function(){
$http.get('/api/testProgress/' + userId).then(function(obj){
$scope.message = obj.data.message;
$scope.sub = obj.data.sub;
if(obj.data.nextPhase){
console.log("Should be cancelling...");
nextScrape();
$interval.cancel(testStart); // This one cancels fine
}
}, function(err){
$interval.cancel(testStart);
});
}, 1000);
function nextScrape(){
console.log("In checkScraperadsfsdfads!")
var checkScraper = $interval(function(){
console.log("In checkScraper REAL!")
$http.get('/api/checkScraper/' + userId).then(function(obj){
var msg = JSON.parse(obj.data);
console.log("Got some data!")
console.log(obj);
if(msg.doneFbs){
$scope.fbMsg = "We've finished gathering " + msg.doneFbs + " Facebook accounts";
}
if(msg.doneTwits){
$scope.twitMsg = "We've finished gathering " + msg.doneTwits + " Twitter accounts";
}
$scope.message = msg.message;
$scope.sub = msg.sub;
if(msg.finished){
$interval.cancel(checkScraper); // This does NOT cancel
console.log("Scraping Done!")
$location.path('/dashboard') // This successfully redirects to the next page
}
},function(err){
console.log("There was an error in Checkscraper ")
console.log(err)
$interval.cancel(checkScraper); // This does NOT cancel when there's an error
});
}, 3000)
}
})
See comments in the code above. Perhaps it's an issue within the nextScrape() function, but I cannot get that $interval to cancel. Even when the $location.path() changes to the next page, the interval is still running.
What am I doing wrong here?
You might have multiple ajax requests at a time if your call takes more than a second to get back. Instead of using $interval, why don't you make one call and use $tiemout to schedule a second call if you need to when the first call is done?
function checkProgress() {
$http.get('/api/testProgress/' + userId).then(function(obj){
$scope.message = obj.data.message;
$scope.sub = obj.data.sub;
if(obj.data.nextPhase){
// move on to next phase
nextScrape();
} else {
// not done, schedule another check
$timeout(checkProgress, 1000);
}
}, function(err){
// error, you cancel, but maybe schedule another progress check?
});
}
I suspect the code is making multiple call before receiving response from the Ajax. That means your ajax is taking more than one second to respond. This is happening because you have mentioned very less amount of time to pool the data from server again.
To deactivate the $interval after page redirection you could take a use of $destroy event on scope. Events needs to be clear manually, because they won't get vanished until we detach them. You could stop interval while leaving the page. Destroy the event on scope event
Code
$scope.$on('$destroy', function(){
$interval.cancel(testStart);
})
I am fetching a data with this function in my controller:
var fetchStoreItems = function () {
return $http.get('/enterprises/_store').then(function (response) {
$scope.items = response.data;
}, function (errResponse) {
console.error("Error while fetching data")
})
};
It is working fine and fast enough. But what if there are lots of items to fetch?! I want to put a spinner while data is being fetched.
How can I do this?
In your controller,
var fetchStoreItems = function () {
$scope.loading = true; //define a `$scope` variable; show loading image when ajax starts
return $http.get('/enterprises/_store').then(function (response) {
$scope.items = response.data;
$scope.loading = false; //hide loading image when ajax successfully completes
}, function (errResponse) {
console.error("Error while fetching data");
$scope.loading = false; //hide loading image when ajax error
})
};
<img src="pathToLoadingImage" ng-show="loading" /> // show the loading image according to `$scope.loading`
If you want to use it for some of the rest API calls, kalhano's answer works well.
However if you want spinner for all your angular http calls, you might consider using an interceptor.
Please check this link for that:
Http call docs with interceptors explained
This is my routing code:
$routeProvider
.when('/', 'main')
.when('/books','main.book')
.segment('main', {
templateUrl:'templates/main.html',
controller:MainCtrl})
.within()
.segment('book', {
templateUrl:'templates/book.html',
controller:BookCtrl
})
These are the controllers:
function Mainctrl()
{
},
function Bookctrl($http,$cacheFactory)
{
var bookCache = $cacheFactory('Books');
var book = bookCache.get("BookName");
if(!book){
alert("first time");
var data=[{"name":"1"},{"name":"2"},{"name":"3"}];
bookCache.put("BookName",data);
} else {
alert("second time");
alert(book);
}
}
First I am loading main.html page. It has one nested view and has one button (Book). When the user clicks on that button I am just loading book.html into that nested view and then within the BookCtrl function I am sending a request to the server to get the data from the server. I am getting a response and I have displayed all data that is working fine. But when I click on that button each time a request is sent to server. So instead of that I have planned to keep all of the data in an array when I click the first time. I have tried by using the above code but when I click for the first time the array is empty so it is pushing data into the array but when I click again it is not showing anything. That means I am not getting any alert. What am I doing wrong?
If you are asking about how to cache items and use them between controllers use cacheFactory
var bookCache = $cacheFactory('Books');
...
var book = bookCache.get("BookName")
//book will be undefined if not cached
if(!book){
//do request to get book
$http.getJSON(url,function(data)
{
var book = {name:data.name,isbn:data.isbn};
//then save it
bookCache.put("BookName",);
//do something with it
showBook(book);
});
} else {
//book was cached, do something with it
showBook(book);
}
you can then access the cache in the other controllers by getting the cache object
function Mainctrl() {
//Will be undefined if it hasnt been created yet.
var bookCache = $cacheFactory.get('Books');
}
I have an AJAX function to check for new messages and then prepend the new messages to the #message. But, my problem is that this function triggers every 20 seconds, but whenever you click the Refresh button that instantly triggers the function, it messes up. Here is my functions for the AJAX:
function ajaxMail() {
var message_id = $('.line:first').attr('id');
jQuery.ajax({ //new mail
type: 'get',
dataType: 'text',
url: "/employee/message/check_mail.php",
data: {
latest_id: message_id,
t: Math.random()
},
success: function(data, textStatus) {
$('#messages_inner').prepend(data);
}
});
}
function updateTitles() {
//if(titleChange !== false) {
$.get('update.php?type=title', function(data) {
document.title = data;
});
//}
$.get('update.php?type=header', function(data) {
$('#heading').html(data);
});
$.get('update.php?type=total', function(data) {
$('#total').html('Total messages: ' + data);
});
setTimeout("updateTitles();ajaxMail();", 20000);
}
updateTitles();
And for the Refresh button this is what I use:
$(document).ready(function() {
$('#refresh').click(function() {
ajaxMail();
updateTitles();
});
});
Sometimes, the same exact message gets prepended to the message div because of the button or something. (but when I refresh of course there aren't 2 of the same message anymore) This is one time when the same message was prepended multiple times:
First, I pressed the Refresh button and it prepended the new message. But then about 5 seconds later the funciton triggered again and for some reason prepended the same message again. Also as you can see the Inbox count says 2 because really there is only 2 ("Test" and "Test12345"), but for some reason the "Test12345" got prepended 2 times.
Does anyone know why it is doing this? I can also provide the code for check_mail.php if you need to see it.
I'd recommend trying cache:false too, I've had browsers caching an ajax request even through I was sending a random string along.
Also, consider clearing the timeout before you set it again, as each time the refresh button is pressed it starts another timeout.