Windy Community

    • Register
    • Login
    • Search
    • Unread
    • Categories
    • Groups
    • Go to windy.com

    Redrawing or reinitialising windyAPI in a single page app

    Windy API v4
    8
    11
    3310
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      abilek last edited by

      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

      1 Reply Last reply Reply Quote 1
      • A
        abilek last edited by

        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.

        M 1 Reply Last reply Reply Quote 1
        • ivo
          ivo Administrator last edited by

          The API is intended to be used in single page app

          1 Reply Last reply Reply Quote 0
          • A
            abilek last edited by

            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

            0_1534840448792_Screen Shot 2018-08-21 at 8.31.49 PM.png

            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.

            1 Reply Last reply Reply Quote 1
            • ?
              A Former User last edited by

              @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.

              1 Reply Last reply Reply Quote 4
              • ivo
                ivo Administrator last edited by

                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)

                1 Reply Last reply Reply Quote 0
                • W
                  wcandillon last edited by

                  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?

                  kriszoza 1 Reply Last reply Reply Quote 5
                  • A
                    andreytsuprik last edited by

                    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.

                    1 Reply Last reply Reply Quote 0
                    • N
                      norchina last edited by

                      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

                      1 Reply Last reply Reply Quote 0
                      • M
                        mantulgan @abilek last edited by

                        @abilek its work, thanks

                        1 Reply Last reply Reply Quote 0
                        • kriszoza
                          kriszoza @wcandillon last edited by

                          @wcandillon Any update?

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post
                          Windyty, S.E. - all rights reserved. Powered by excellent NodeBB
                          NodeBB & contributors, OSM & contributors, HERE maps
                          Terms and Conditions     Privacy Policy