We have a complex web mapping app using arcgis JavaScript api. The following code is used to inform the ui that the map layers are loaded:
on(map,"update-end",function(){
//emit event to ui module
});
map.addLayers(layers);
The application frequently adds and removes map layers. However occasionally something is going wrong and although layers get added the update-end event doesn't get fired, despite the layers completing load. After this happens the event wont fire again unless the app reloads.
Does anyone have an idea under what conditions this may occur? How can we prevent the problem?
I usually put my map.on("update-end", endUpdateMap); sentence after any map.addlayer() in the same javascript where you are defining your layers. It works fine for me.
map.on("update-end", endUpdateMap);
function endUpdateMap(error) {
esri.hide(loading);
map.enableMapNavigation();
map.disableDoubleClickZoom();
map.showZoomSlider();
}
I had this issue, I think there is actually a bug in the JSAPI. If you remove a layer whilst it is updating then it actually breaks the "update-start" and "update-end" events, they stop firing completely. I will try and put a test case together at some point but I found with a slow drawing layer, like an image service, the issue was very prevalent.
Anyway, I had to think of a way around it and this is what I came up with:
this.layer.setVisibility(false); // set invisible first to ensure spinner stop
this.map.removeLayer(this.layer);
Related
So I have a very specific problem that presented itself recently (right before our planned launch day tomorrow) and I am not completely sure how to solve it. I have built our website of an HTML-template with my modest front-end skills and we are very pleased with it. However, I can't seem to solve this.
The problem:
I have a filter system that allows a user to filter articles that are presented on a page. A user can even fill in this filter on the home page, direct to the page with the articles and have the filter applied. However, if then the filter is broadened (less strict) and new articles present itself, the pictures do not show up. Found out this is the case because the flexslider behind it has to be initialized again which happens on a window load (e.g. when the window is resized). The function that controls the initialization of the flexslider is in an external js file and I am not sure whether I can call on it from my own custom.js file, so I am thinking of just calling a resize/reload window function to active it.
The question:
Can I run a resize window function (or something that activates the flexslider) without hindering user experience (more specifically, without ACTUALLY resizing/reloading the window)? I will run this on a change in the filter.
I know this is a very specific question but hopefully somebody can help me out.
Take care!
p.s. it would be ideal if I could run the actual function that loads the flexslider but this is located in an external js file.
EDIT:
Briefly some additional info. If I go straight to the article page, it has no filter active and thus shows all articles, if I then start flipping through the filter, all is good. It is however only if I arrive from the homepage with a set filter that the problems arise. You then arrive on the article page which shows only the articles that are within the boundaries, and when the filter is taken away it has problems loading the images of the new articles showing up. As if it had not loaded these because they were not open on window load the first time.
You can trigger a resize event by creating a new event and passing it into the dispatchEvent command on window. There's a nice guide here. You'll want the type of event to be resize, since that's what it's listening for.
window.dispatchEvent(new Event('resize'))
This will work for events that were added via jQuery as well as events added via addEventListener.
I managed to solve it after all by delaying the function that drops the filter values into my inputs so it loads in all images initially before applying the filter. It happens at such speed it's hardly noticeable.
Also, I did try to initiate a window resize function, it did work without actually resizing anything, but unfortunately the images did not load in properly (overlap and such).
Anyway, it has been solved. Thanks for all the input!
I'm trying to play with Google Maps API.
My HTML code looks like:
<div id="map-1"></div>
I use some JS to init map on the page, nearly similar to this one:
var mapInstance = new google.maps.Map(document.getElementById('map-1'));
It works well.
The issue is, I need to add and remove a maps on a same page multiple times (when user clicks on corresponding links).
I haven't found anything about how to remove a map from the page - with all the html changes and events it brings on initialization https://developers.google.com/maps/documentation/javascript/reference
There're some methods like clearInstanceListeners, which are likely related mostly to the points and overlays, not to the map itself (I suppose it should remove a zoomin/out, doubleclick and other events).
I've tried something like google.maps.event.clearInstanceListeners(mapInstance);. It doesn't work - my map doesn't loose any events.
The reason why I'm asking for this is the memory leaks. I suppose that if I create nearly 50 maps on my page without successfully destroying them, my page will use too much memory (because events are still in memory if only an HTML is removed) and as a result, overall performance of the page will dramatically slow down.
Do you have any ideas about how this issue can be solved?
I've also seen a topic Google Maps JavaScript API V3 - Unload / Deconstructor / Delete / Remove
They recommend to use jQuery.remove().
I don't think it's a right case for me, because:
1) I simply don't use jQuery in my project
2) remove method removes events only from jQuery's cache (events which were binded by jQuery)
3) as a result of the 2), html is removed, but memory isn't cleared (hello memory leak).
I encountered the same issue recently. First, Have you try it? It doesn't end in a memory leak every time... It should be really quick to test on your computer.
Anyway, in my case, I solved the memory leak issue updating only the data (I used a heatmap overlay) and keeping all the way long the same google map. I'm not sure it's exactly what you're expecting but hope it helps..
First, some background. I'm fairly certain this is not because of zombie views. I use requireJS and I have only one instance of main views at any given time.
Also, this behavior is random, I haven't been able to reproduce it even once, but several of my users have pointed it out and shown me a video where every click on the app seems to trigger the handler twice. The clicks happen very very fast. It can't be mechanical failure of the mouse because the problem has been reported on multiple machines. The reports are from people with fast Internet connections, for what it's worth.
Is it possible that two instances of the app are running at the same time? Are there any steps I can take to isolate a problem of this kind in backbone?
Apologies for the wall of text, please let me know if I can put up any extra information or relevant pieces of source.
Edit : I've managed to recreate this in Opera. After stepping through part of the code that fires twice (I was inspecting code that opens a modal), I was able to look at the view that triggers the event. Both views have the same CID, so this cannot be attributed to Zombie views right?
In my experience, this is almost always related to zombie views, or other DOM leaks. My best friend in this case if the Web Inspector Profiles -> Take Heap Snapshot and look for detached DOM tree (type "detached" in the search field).
It can occur in tricky cases, even if you think you're only instanciating views once.
Beyond that, you'll have to show us some code ;)
The problem here was that I was running a third party library that reports JS errors. Due to a n error on their part, event bindings on page were affected and this caused the confusion inside the application.
Moral of the story - Whenever you hit an error you feel is impossible, remove your third party dependencies one by one and confirm the problem is your fault to begin with.
I am building a third party plugin to the popular platform Atlassian JIRA and where I have implemented a calendar. However when I click on a day outside any event, it triggers a function which will trigger the #create_link event.
When that event gets fired a new modal window opens and the user may fill out a new issue. The thing is that I want to change the issuetype field and then fill in one field automatically. However, I have no idea how to generate a new window with these result (I don't think it's possible) and therefore my only option was Javascript events.
This is my code so far:
jQuery.when(AJS.$('#create_link').trigger('click')).done(function() {
jQuery.when(jQuery('#issuetype-field').trigger('click')).done(function() {
jQuery('.aui-list-item-li-event').find('a').trigger('click');
});
});
//I have also tried to use `.then`
The thing is, the triggers work when run separately in console but it seems like the jQuery.when doesn't. Because the next event triggers long before the window has been loaded.
What I need is a way to wait to trigger the last 2 events by using callbacks on the triggers or what not. How can I solve this problem? Also, if anyone know how to create a new issue window with js in Jira that is also a very acceptable answer.
Using Jira issue collector would make your task much simpler. You can configure it to receive feedback or bug reports etc.
https://confluence.atlassian.com/display/JIRA/Using+the+Issue+Collector
The integration of the issue collector is merely adding a script tag in your HTML page
I'm probably missing something really obvious here...
I'm showing a dialog box with progress bar during page load. The dialog and progress bar are both jQueryUI widgets. There are a couple of phases of loading - the page makes a load of jQuery $.get() requests to load resources, then on the $(document).ajaxStop() event, does things with those resources. I'm updating the progress bar and some status text throughout this process.
The issue is that as soon as the ajaxStop event fires, updates stop. The code works nicely during resource loading, but then freezes and I don't see any of the updates during processing. If I put a breakpoint on a post-ajaxStop update in Chrome and step through the code, the screen updates correctly so I know that the code works.
Can anyone explain why everything updates nicely during my AJAX loading phase, but then stops on the ajaxStop event? Is there an easy way to make updates continue afterwards?
Thanks!
Several hours of searching later, the following blog pointed me in the right direction:
There's a jQuery extension described in the entry which allows you to define two functions, one to compute and one to update the UI. It schedules them alternately using the setTimeout function.
I've had to rewrite my code in something akin to continuation passing style so that each function schedules its continuation to run using setTimeout. This returns control to the browser for long enough for the screen to be updated.
This feels like a bit of a hack though to get round browser/Javascript limitations. Anyone know of a better way?