Redrawing or reinitialising windyAPI in a single page app
-
Hi there,
I am evaluating windyAPI for (paid) use in a single page app. I'm trying to figure out the best way to redraw or reinitialise the map once I've navigated away so that < div id="windy" > has disappeared from the DOM.
When I navigate back < div id="windy" > is again part of the DOM but needs to have windyAPI reinitialised. When I try to rerun windyInit, I get many errors along the lines of "tinyrequire DI error: Object W.glAnimation already exists" "tinyrequire DI error: Object W.glVector already exists"
Is there a way to reset W back to preinit state?
Thanks,
Anne -
Follow up solution for this issue is to copy the preinit W global somewhere, then reset W from that copy before reinitialising. I put something similar to this snippet before my call to windyInit()
if (!window.copy_of_W) {
window.copy_of_W = Object.assign({}, window.W);
}
if (window.W.windyBoot) {
window.W = Object.assign({}, window.copy_of_W);
}Hope this helps someone.
-
The API is intended to be used in single page app
-
Interesting. The code I'm running is something along the lines of
# if !copy_of_W # copy_of_W = _.extend({}, W) # if W.windyBoot # W = _.extend({}, copy_of_W) windyInit(options, (windyAPI) -> { map } = windyAPI lat = track.points[0].latitude lon = track.points[0].longitude L.marker([lat, lon], { title: track.aircraft }).addTo( map ) pointsArray = [] _.forEach(track.points, (point) -> pointsArray.push([point.latitude, point.longitude]) ) L.polyline(pointsArray, { color: 'red' }).addTo( map ) )
The first time the route loads, everything works like a charm. If I navigate to a different route then back again, windy reloads in the default view, with no options and no markers, and the following console errors
If I uncomment
if !copy_of_W copy_of_W = _.extend({}, W) if W.windyBoot W = _.extend({}, copy_of_W)
windy reloads as expected, with the options and the markers etc.
-
@abilek solution is good to everyone using some single page application framework (we are using Angular).
Using his way you can inicialize the map every time you change the page you are in or the windy div disappears.
But there is a problem with this, every time you call windyInit it will load the lib.css and lib.js files again. This causes the browser to start consuming more memory every time you call the windyInit function.To mitigate this you can remove the loaded css and js files.
You can test this in Google Chrome console
$$('head > link[href^="https://api4.windy.com"]').forEach(function (a) { a.remove() })
$$('head > script[src^="https://api4.windy.com"]').forEach(function (a) { a.remove() })It removes any css and js files with the api4.windy.com domain. If you use the api4.windy.com server to get the libBoot.js file then make the selectors more specific so you don't end up deleting the libBoot.js file.
@ivo comment is somewhat wrong. Windy acts as single page app, but it can't be used as a component/part of a single page app. Because single page apps will not reload the page and the problems described by @abilek will occur.
I think windy should have two methods, one for bootstrapping (authentication + lib loading) and another to initialise the element.
This way you could run the bootstrapping once, and then init has many time as you want without loading the same lib.js and lib.css files. -
Unfortunately there is hurricane season I can put some efforts into dev of API4 after it ends.
So far I suggest to create
<div></div>
, leave it on page, and just use your framework to hide it (via z-index, display: now, or whatever) -
I'm hitting the same issue with React. It's not clear to me what I need to clean up in the componentWillUnmount() phase. Alternatively, I would like to know if it's possible to get windy as an NPM package?
-
I've faced such kind of issue recently. I tried removing global W, but this didn't work for me. However, I've found a solution.
The point is that we use Backbone.js framework in our project. it is an MVC framework which separates it's views from other componenets by creating something like virtual scope for each view.Therefore I simply included initialization of windy into one of the views. When I need to start windy I create the view and render it on the page. After finishing working with it i dispose the view by calling it's unbind() and remove() methods. Seems like this operations somehow manages to clear the page's scope from all Windy's records.
When I am to show the forecast map again I initialize the view again and render it as it has never been created before. The map is been created succesfully and without any significant redundant artifacts like we all got used to encounter.
Hope this helps. If somebody is interested in any further details or examples, please contact me via email andreytsuprik@yandex.com.
-
Hi all,
I'm facing exactly the same issue with Angular 4 application. Whatever I do, I cannot get rid of "Object W.[something] already exists". I've tried the proposed solutions from this thread, but getting a reference of window.W doesn't seem to work. Did anyone manage to solve this problem in Angular?
Many thanks,
Ivo -
@abilek its work, thanks
-
@wcandillon Any update?