Angular Error In FireFox When Changing Urls - angularjs

I have a function in an angular factory that gets invoked when my page is loaded. There's a controller which invokes this factory method.
Looks something that looks like this.
factory.getData = $http.post('/LocationOfData/Here').
then(function(response) {
// stuff happens here when successful
}, function (response) {
console.log('an error has occurred');
});
I noticed that my page works correctly as in //stuff happens here when successful gets hit... but only when the page fully loads.
If I load my page and then very quickly click on a link taking me to a different page within my app, an error occurs. (as in the console.log.)
This only seems to happen in FireFox. everything works ok in Chrome.
Any suggestions on what I should change or look out for?
EDIT: The response Object is
Object { data: null, status: 0, headers: headersGetter/<(), config: Object, statusText: "" }

Normally in JavaScript while when the page is loading if you are injecting any scripts it will consider it as one of the parallel process,if you disabled the cache of the browser it will not consider the parallel process and it will kill the process,in your case while the page load you are doing a service call and the call will be treated as a separate thread or process in chrome if you are not disabled the cache,you may get the service to fail in Chrome as well if you disabled the cache
Its an assumption only,may help:)

Related

AngularJs $http get not working 1st time but does on subsequent invocations

All:
I have an Iframe tag on a simple HTML page and inside this Iframe tag is a HTML form - lets call it a widget. Its a form where the user can enter search criteria and click on a button to obtain the search results. I have decided to use Angularjs to make the necessary DB calls to a REST service that returns the search results back to the widget for display.
In testing this I enter a value in a textbox on the widget, that value being a value that I know exists in a particular table I'm testing against.
Here is my $http get call:
$http
.get('http://localhost/XXXXService/folder/getfolders/' +
$scope.formData.srchterm **==>** mapped to search textbox
).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
//$scope.formData = response;
//$scope.nrdFolderDataArray = response;
console.log('Success retrieving data.');
console.log(response.length);
console.log('response:');
console.log(response);
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log('Error occurred retrieving data.');
console.log(response.status);
console.log('returned data count:');
console.log(response.size);
console.log('response:');
console.log(response);
});
This call is inside a function called "submitForm" that is mapped to the widget with a "ng-submit="submitForm()" attribute on the submit button. And yes there are several log statements so I can try and figure out what is going on here. And what is happening is this: after entering a value in the textbox, THE FIRST TIME the search button is clicked the .get command does not work. I does not make the call to the REST service. I know this because I wrote the REST service and made sure I put in plenty of log statements while doing so and there are no log statements in the log file from the REST service. Instead the errorCallback block runs and I see all those log statements in the console. The "response" (object?) after THE FIRST call looks like this:
Object {data: null, status: 0, config: Object, statusText: ""} Method = GET Status = (canceled) type xhr
Further, in FF there is no response data to view in the Net tab of Firebug upon THE FIRST call, but there is response data to view in all subsequent calls.
So, interestingly enough each subsequent invocation of that $http.get call works! I see log statements in the log file from the REST service method and the successCallback block runs and I can see my data via those console.log messages.
Also, if I were to change the search value in the text box, which would then be THE FIRST TIME we would be searching for data for that new key, once again, the call does not work, but does work on subsequent clicks on the "search" button for that new key value.
I really am not sure if I have a CORS issue here since, other than THE FIRST calls each subsequent $http.get call works like a champ. Its just that very first call or first call after the search key has changed that the $http.get does not want to work.
I have tried setting headers in the .get call and I have tried using
#CrossOrigin(origins = "http://localhost/7001") as per
https://spring.io/guides/gs/rest-service-cors/ but I continue to have this issue on the first time invoking this .get call.
I've been dealing with this issue for way too many hours now and would sure appreciate some input as to why this is happening.
I'm sorry for being verbose here. I wanted to explain my issue thoroughly.
Please help.
Thank you
-g

Loading message shown on $routeChangeStart disappears as soon as LESS CSS starts compiling

I've created a pretty heavy AngularJS application which has many dependencies (JS libraries and LESS css). When the application URL is hit, it determines the route based on login status and redirects to login route if not logged in. The problem is, until the route is redirected to, and the HTML is loaded, the page remains completely blank for almost 4-5 seconds, which looks really confusing.
I tried to implement some message using $routeChangeStart but it's not giving me the desired results. I want the 'loading..." message as soon as URL is hit and until app is routed and HTML is fully loaded. But the message is disappearing after a couple of milliseconds.
$rootScope.$on('$routeChangeStart', function() {
$rootScope.layout.loading = true;
});
$rootScope.$on('$routeChangeSuccess', function() {
$rootScope.layout.loading = false;
});
UPDATE: The problem seems to be the LESS CSS which is being compiled and loaded to get the page ready. The loading indicator text correctly works without LESS CSS (see this Plunker)
In the actual application, I have put the loading indicator text after the body tag, and there are many JS scripts (including LESS.js) after the indicator text. The loading indicator shows until LESS starts compiling, and disappears as after compilation starts. Any solution to this?
I believe .run() method of angular can solve your issue, Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kick start the application. It is executed after all of the services have been configured and the injector has been created.
You can try the following to show/hide loader when your application is loading.
.run(['$location', function ($location) {
// if your application URL os https://myApplication/Login/loginStatus
if ($location.path() === '' && $location.$$absUrl.indexOf('/loginStatus') > -1) {
// show loading
// some code here to return route based on login status for example,
var promise = getLoginStatus();
promise.then(function (result) {
// redirect to the route as per login status
$location.path(result); //Where result is route url.
// hide loading
});
}
}]);

Angular Google Map, lazy loading, second time

I'm using angular-ui.github.io/angular-google-maps/
I use the recommended lazy loading technique, I have this in my app.js:
.config(function(uiGmapGoogleMapApiProvider) {
uiGmapGoogleMapApiProvider.configure({
// key: 'your api key',
v: '3.20' //defaults to latest 3.X anyhow
//libraries: 'weather,geometry,visualization'
});
})
And at some point in my controller, I execute this:
var uiGmapGoogleMapApiTimer = $timeout(function() {
reject("uiGmapGoogleMapApi didn't respond after 10 seconds.");
}, 5000);
console.log('DUDE.01');
uiGmapGoogleMapApi.then(function(maps) {
console.log('DUDE.02');
$timeout.cancel(uiGmapGoogleMapApiTimer);
geocoder = new google.maps.Geocoder();
resolve(geocoder);
}, function(err) {
console.log('DUDE.03');
});
So, when I'm offline, the timer will kick in, and I send the user back to the login page. (Originally I simply exit the app. It works in android, but in iOS it doesnt work, it's in fact forbidden by Apple).
So... that's why now I'm sending it back to login page.
Now, in the login page, I reactivate my wifi.... and once I'm back in the page that (is supposed to) show the map.... it breaks. The success handler of uiGmapGoogleMapApi.then never gets called. (Dude.01 gets printed, but Dude.02 nor Dude.03 get printed).
So... that page (wrongly) thinks that the device is still disconnected.
I suppose it's because the loading of google map javascripts is only done once (during load -- that´s why if I close my app, and return back, things will run just fine).
So... it's not really lazy loading (?). Or... if it's lazy loading, it doesn't seem to support scenarios like... try loading it the second time (if the first time failed because of connectivity).
Is anyone familiar enough with the source code of angular-ui.github.io/angular-google-maps/ to suggest what's the solution for this problem?
I looked at the logs I put in the library's code... I came to the conclusion: I need way to get line 183 to be re-executed on the second time I call uiGmapGoogleMapApi.then ... Currently it doesn't. It only gets called the first, when I start my app, and having internet connection since the beginning.
And based on what I understand from this doc on "provider", I need the uiGmapGoogleMapApi to be reinstantiated (right before) the second time I try to use it.
https://docs.angularjs.org/api/auto/service/$provide
Is that right? How?
Looks like I'm battling against provider caching here. Because I use dependency injection in my controller to get reference to uiGmapGoogleMapApi. (I have .controller('myctrl', function(uiGmapGoogleMapApi) {...})
what I might need is:
.controller('myctrl', function() {
var uiGmapGoogleMapApi = $injector.get('uiGmapGoogleMapApi');
//or something along that line maybe
})
I just tried it, still doesn't work.
Please help.
Thanks,
Raka
Well, my "solution" is: instead of going to login page, I simply refresh the app., by setting the current url of the window object to index.html.

Extjs panel loadmask not working on chrome

I have a panel and on click on a button I am calling a Ajax call. on firefox I could see the loadmask on panel but on chrome it is not working. Even I create a separate mask object before Ajax call but it only shows after Ajax call complete. I could show/hide mask using browser javascript console but somehow it is not working when Ajax call running my Ajax call is sync. and issue with chrome only.
jsfiddle.net/naveen_ramawat/6d7pyohL/2/
Use a mask for the whole body
Ext.getBody().mask('your message');
before ajax call and use,
Ext.getBody().unmask();
inside ajax success
Updated jsfiddle- http://jsfiddle.net/yq8e7na8/3/
(set a timeout before asynchronos ajax call)
Try this code instead:
panel = Ext.getCmp('panel');
var myMask = new Ext.LoadMask(panel , {msg:"Loading..."});
myMask.show();
Then you can hide in the success callback function:
myMask.hide();
This is the thing:
my Ajax call is sync. and issue with chrome only
Sync AJAX has been deprecated and Chrome actually does not process it anymore, showing this warning in console:
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help,
check http://xhr.spec.whatwg.org/.
Use async AJAX.
UPDATE:
Chrome actually seems to process the sync AJAX request, however, showing the load mask falls through. It looks like, unlike Firefox, Chrome does not wait for the interface to actually render the mask before moving onto the next bit of JavaScript code. And because the next bit is a sync AJAX call which is freezing everything, followed by myMask.hide() — we never see the mask.
To see the mask in Chrome, you can put a small delay (1 millisecond was enough on my machine) after myMask.show();:
handler(){
var myMask = new Ext.LoadMask(mypanel , {msg:"Loading..."});
myMask.show();
setTimeout(function(){
Ext.Ajax.request({
url: '/echo/js/?delay=5&js=',
method: 'GET',
async: false
});
console.log('hiding mask');
myMask.hide();
}, 1);
}
During the delay, the mask is rendered before the browser freezes making sync AJAX call.
Working fiddle: http://jsfiddle.net/6d7pyohL/4/
var myMask = new Ext.LoadMask(Ext.getBody(),{msg:"please wait..."});
$(document).ajaxStart(function(){
myMask.show();
});
$(document).ajaxComplete(function(){
myMask.hide();
});
jQuery.ajax({
url:"abc.php",
async:true,
type:"POST",
success:function(data){
}
});
instead of async:false, use async:true

forcing non-async XMLHttpRequest in mobile safari

I have the following code setup on a webpage(private at this time):
function DoRequest(httpReq,url,param){
httpReq.open("POST",url,false);
httpReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
httpReq.send(param);
httpReq.onreadystatechange = function() {
if (httpReq.readyState==4) {alert(httpReq.responseText);}
}
if(httpReq.status==200){
return httpReq.responseText;
} else {
return httpReq.status;
}
}
When I run a request through this, via firefox, safari, ie 7-9, chrome etc on the pc I get a 200 status and the text back correctly.
When I run this same exact page on my iphone, or ipad, I get a status of 0, response text of nothing, and an alert from that callbackfunction of the correct response text afterword. Which seems like it is not waiting for the request to finish before proceeding through the code for the mobile safari browsers, is there anyway to better force it to wait, or a flag I'm blind to see?
I also only get the onreadystate callback on safari, it doesn't do it in any other browser, I tried removing the function in case that was somehow triggering it to run async instead of of not but no dice there it still runs async despite the 3rd parameter being false.
I also just tried httpRq.open("POST",url); without the 3rd parameter and without the onreadystatechange function and still runs async.
The url is an absolute path.
Mobile Safari does not support synchronous use of XMLHttpRequest (third parameter to open is false in your code, which is unsupported).
Anything that depends on the results of the request should get moved into a callback function, and called in your onreadystatechange function right where you have the alert() call.

Resources