I am using AngularJS to constantly poll for new data through HTTP POST. An alert will be sent when new data is received. The code which is inside a controller looks something like this;
var poll = function() {
$http.get('phones.json').success(
function(data)
{
new_val = data.val;
if ( (new_val!== old_val) )
{
$window.alert("AlertEvent");
}
old_data = new_val;
$timeout(poll, 500);
}
);
};
poll();
This code works when the html page is refreshed. Working means when phones.json is changed, an alert will appear. However, if I leave the page on for, say 30 minutes, and come back later, it stops working. I have to refresh the page to get it working again.
What else did I miss out? What did I do wrong? Could it due to some caching mechanism?
Thank you very much.
EDIT: I found the cause. It is indeed due to the browser reading from cache. I can see this using Chrome Developer tools. How can this caching be disabled for this html page only?
You may be able to bust the cache by doing something like this:
$http.get('phones.json?v=' + Date.now())
Depending on how your back-end is set-up you may need to adjust it to accept that.
Related
I have an app I'm working with that is behaving like this... You visit a url /refresh, and it loads the page with a loader/spinner/bar showing for like 5 seconds, then it refreshes the page after it's done. It does this so it can load the latest data that was computed during /refresh.
Right now I am just setting a timeout longer than the loader will most likely stay around, but this is brittle because a bad network connection could put it over the line.
How can I instead "watch" for when the refresh happens? What technique would you recommend. It seems to start to get hairy pretty fast.
Into the nitty gritty, when the loader is showing, when it finishes it is gone for like a half a second before the page reload. So I can't just wait til the loader is gone. It seems like I need to keep some sort of state variable around in the DOM like in localStorage, but can't pinpoint it. Would love some help.
well you could "watch" for the element that display the data using page.$(selector), or if no such element you could also wait for the specific request 's response:
const waitForResponse = (page, url) => {
return new Promise(resolve => {
page.on("response", function callback(response){
if (response.url() === url) {
resolve(response);
page.removeListener("response",callback)
}
})
})
};
const res = await waitForResponse(page,"url of the request you want to wait for");
Wait for Network request before continuing process
I have a question about an order in code. I wanted to create a cookie with a language, and then use the function l to translate. This is the code:
<script>
var lang = navigator.language;
if (document.cookie.indexOf("LANG=")==-1) {
if (lang=="pl"||lang=="en-US") {
document.cookie = "LANG="+lang+";domain=xxx;path=/";
} else {
document.cookie = "LANG=en-US;domain=xxx;path=/";
}
}
</script>
<?php
include 'translations.php';
function l($t) {
global $trsl;
$l = $_COOKIE['LANG'];
if ($l=="en-US") {
return $t;
} else {
return $trsl[$l][$t];
}
}
?>
The problem that I find when I enter the website is that when you enter for the first time, it shows me an error saying that the requested cookie is not defined. But when I press Ctrl+F5 everything goes back to normal. I guess that the php code loads before the js code, but why is that? Is there some way to prevent it?
When you mean enter the website, you mean load the script for the first time?
You are confused about where each script is processed. Javascript as you write it is mean to load up and processed on the browser, while the php will be run on the host machine. So you php will be triggered and running before the whole thing is loaded up in the browser. hence the error.
If you are confused and want to know how it happen, trigger up chrome dev tools and swith to tab network. Then open the page and see header part of the request (make sure its show all / html). Then push f5 and compare from before. You will see that cookie header is assigned on the second request.
Hope it answer your question.
I´ve recently started using horseman.js to scrap a page with node. I can´t figure out how exactly it works and I can´t find good examples on the internet.
My main goal is to log on a platform and extract some data. I´ve managed to do this with PhantomJS, but know I want to learn how to do it with horseman.JS.
My code should open the login page, fill the login and password inputs and click on the "login" button. Pretty easy so far. However, after clicking on the "login" button the site makes 2 redirects before loading the actual page where I want to work.
My problem is that I don´t know how to make my code wait for that page.
With phantomJS I had a workaround with the page URL. The following code shows how I´ve managed to do it with phantomJS and it works just fine:
var page = require('webpage').create();
var urlHome = 'http://akna.com.br/site/montatela.php?t=acesse&header=n&footer=n';
var fillLoginInfo = function(){
$('#cmpLogin').val('mylogin');
$('#cmpSenha').val('mypassword');
$('.btn.btn-default').click();
};
page.onLoadFinished = function(){
var url = page.url;
console.log("Page Loaded: " + url);
if(url == urlHome){
page.evaluate(fillLoginInfo);
return;
}
// After the redirects the url has a "sid" parameter, I wait for that to apear when the page loads.
else if(url.indexOf("sid=") >0){
//Keep struggling with more codes!
return;
}
}
page.open(urlHome);
However, I can´t find a way to handle the redirects with horseman.JS.
Here is what I´ve been trying with horseman.JS without any success:
var Horseman = require("node-horseman");
var horseman = new Horseman();
var urlHome = 'http://akna.com.br/site/montatela.php?t=acesse&header=n&footer=n';
var fillLoginInfo = function(){
$('#cmpLogin').val('myemail');
$('#cmpSenha').val('mypassword');
$('.btn.btn-default').click();
}
var okStatus = function(){
return horseman.status();
}
horseman
.open(urlHome)
.type('input[name="cmpLogin"]','myemail')
.type('input[name="cmpSenha"]','mypassword')
.click('.btn-success')
.waitFor(okStatus, 200)
.screenshot('image.png')
.close();
How do I handle the redirects?
I'm currently solving the same problem, and my best solution so far is to use the waitForSelector method to target something on the final page.
E.g.
horseman
.open(urlHome)
.type('input[name="cmpLogin"]','myemail')
.type('input[name="cmpSenha"]','mypassword')
.click('.btn-success')
.waitForSelector("#loginComplete")
.screenshot('image.png')
.close();
Of course you have to know the page you're waiting for to do this.
If you know there are two redirects, you can use the approach of .waitForNextPage() twice. A naive approach if you didn't know how many redirects to expect would be to chain these until a timeout is reached (I don't recommend this as it will be slow!),
Perhaps a cleverer way, you can also use on events to capture redirects, like .on('navigationRequested') or .on('urlChanged').
Although it doesn't answer your question directly, this link may help: https://github.com/ariya/phantomjs/issues/11507
Super new to AngularJS so please be patient with me :)
We're using it to poll our API for updates while we process a repository (and after). On one particular page the data is loaded but not drawn to the screen. Highlighting the content, or resizing the browser causes a redraw and shows all angular values that weren't there a moment ago! Latest Chrome!
Just look: Everything starts at "0" or "-" but highlighting the page reveals "Optimized Images" and "Filesize Savings" content changes.
Live example:
MAY REQUIRE YOU HIT REFRESH TO HAVE THE ANGULAR DRAW FAIL
REQUIRES CHROME ~ Version 31.0.1650.63 m
It works on Firefox!?!
http://crusher.io/repo/alhertz/didthesaintswin/63f49d36e709dea172fe7e4bbacbcfd834f9a642
This appears to be very similar to this question, but there is no nested controller issue I can detect: Update page contents after GET request in AngularJS
When I try to add a $scope.$apply() I get this error: http://docs.angularjs.org/error/$rootScope:inprog?p0=$apply
This is the relevant code in the angular controller (coffeescript):
do poll = ->
$http.get("#{$location.absUrl()}/poll.json").success((data, status, headers, config) ->
if $scope.continuePolling
#console.log("still polling #{$location.absUrl()}")
$scope.data = data
$scope.TotalOptimizedImage = $scope.CalcTotalOptimizedImage(data.images)
$scope.TotalImgSize = $scope.CalcTotalImgSize(data.images)
$scope.SavedImgSize = $scope.CalcSavedImgSize(data.images)
$scope.TotalSavings = ($scope.TotalImgSize - $scope.SavedImgSize + 0)
$timeout(poll, 10000)
)
Really not sure how to break this apart for fixing. Thoughts?
It looks like you need to call $scope.apply inside the callback to the http.get. The reason is that the callback will happen outside the controller digest. Sorry I'm not adept at coffee script but something like this:
$http.get("#{$location.absUrl()}/poll.json").success((data, status, headers, config)
if $scope.continuePolling
$scope.$apply(function() { // wrap the stuff you want to update in the $scope.$apply
#console.log("still polling #{$location.absUrl()}")
$scope.data = data
$scope.TotalOptimizedImage = $scope.CalcTotalOptimizedImage(data.images)
$scope.TotalImgSize = $scope.CalcTotalImgSize(data.images)
$scope.SavedImgSize = $scope.CalcSavedImgSize(data.images)
$scope.TotalSavings = ($scope.TotalImgSize - $scope.SavedImgSize + 0)
});
$timeout(poll, 10000)
)
I would suggest that you use a safeApply function and there is a great timeFunctions service that might help you with the polling that I've used quite successfully in a couple projects. You can find it in this answer.
Am having an issue with Safari. I have a basic script using jQuery that makes some changes to a form field and adds some behaviours to it. When I run this script on using the document ready method it's fine in Firefox but in Safari it doesn't always run the initial changes. I can hit refresh and get it running fine 4/5 times, but sometimes it just doesn't initialise like it should.
This is running on a local server so the refresh is pretty quick, I'm wondering if the javascript is executing before the page has finished loading. I've tried calling the script in the foot of the page rather then the header but that hasn't helped. I remember hearing about different browsers firing document ready at different times and thought this would help remedy it but it hasn't and I can't find any further information on that topic.
Anything I'm missing that could be the issue or a workaround? The script itself doesn't seem to be at fault. Am using the jQuery colours plugin, apart from that it's only jQuery and my script.
Help is always appreciated, thanks people!
Here is the code. initSearchBox() is run using the line below in the header.
$(document).ready(function() { initSearchBox() ; });
function randomFieldValue(){
var options = new Array(
'Lorem',
'Ipsum',
'Dolor',
'Sit',
'Amet'
)
t = Math.floor(Math.random()*(options.length - 1));
return options[t] ;
}
function initSearchBox(){
instanceDefText = randomFieldValue() ;
$('#search-form-field')
.attr('value',instanceDefText)
.css('color','#fff')
.animate({color:'#999'},1500)
.focus(function(){
if($(this).attr('value') == instanceDefText){
$(this).attr('value','')
.css('color','#000')
}
})
.blur(function(){
if($(this).attr('value') == ''){
instanceDefText = randomFieldValue() ;
$(this).attr('value',instanceDefText)
.css('color','#fff')
.animate({color:'#999'},1500)
}
});
}