Reputation: 663
I want to check for Internet connection by hitting a pixel on public cloud. Based on the response I want to show an alert whether user is connected or not to Internet. Following is the code for pixel load($q is injected in the service, which has below function):
hasInternetConnection = function(pingUrl){
var img,
pingUrl = Constant.ImageUrl;
var deferred = $q.defer();
img = document.createElement('img');
img.onerror = deferred.reject(false);
img.onload = deferred.resolve(true)
img.src = pingUrl;
return deferred.promise
}
Now based on its return value I want to do following:
var con = hasInternetConnection()
if(!con){
alert('No connection')
}
But this is not working. Any suggestions?
How can you test the alert popup in unit testing?
Thanks.
Upvotes: 1
Views: 799
Reputation: 19288
To overcome issues you probably aren't even aware of, try Offline (3kb minified and compressed), or at least read the README.md.
You'll see that the author moved away from hitting a cloudfront hosted file in favour of (by default) '/favicon.ico' (on same origin) or anything that will give a 204 (No Content).
The image technique is deprecated because a 404 (File Not Found) can't be distinguished from a genuine connection issue. From v0.7.0, Offline checks with an XHR, under which even a 404 (or 204) means "connected".
With Offline, you also get some great sugar such as 'checkOnLoad', 'interceptRequests' and 'reconnect' options.
Upvotes: 0
Reputation: 707686
There are many things wrong in both your understanding of how to use a promise for this task and even how to assign callbacks to the image.
Here's a cleaned up version of your function:
function hasInternetConnection() {
var timer, timeoutTime = 4000;
var defer = $q.defer();
var img = new Image();
img.onload = function() {
clearTimeout(timer);
defer.resolve(true);
}
img.onerror = img.onabort = function() {
defer.resolve(false);
}
img.src = Constant.ImageUrl + "?rand=" +
(Math.random() + "").replace(".", "") + "_" + (new Date().getTime());
// set max time to wait
timer = setTimeout(img.onerror, timeoutTime);
return defer.promise;
}
hasInternetConnection().then(function(connected) {
if (connected) {
// have internet here
} else {
// no internet here
}
});
Working demo: http://jsfiddle.net/jfriend00/2xr4rzqq/
Summary of changes/fixes:
.then()
handler.onerror
and onload
to be actual function references that can be called later..resolve()
since it seems easier for the caller to just check the promise value boolean rather than have two handlers. This is purely a design choice.pingUrl
argument since you weren't using that argumentnew Image()
instead of document.createElement("img")
onabort
handler for completeness.Upvotes: 3