Does Picture.reloadSource work?

I found this thread on the forum:

Can some dev just confirm that reloadSource is working correctly? I’m using 2.3.1

I’m trying to make a Picture reload its source, but it doesn’t seem to be doing anything.
The code snippet below is what i do. I can see the console print that it found the correct groups, but when i open my browser’s network inspector it doesn’t seem to be sending out a new request to get the latest version of the image. I even tried redraw, nothing seems to work.

Note that the URL stays the same, but the image that the url points to was changed in the backend.

  diagram.commit(function (d) {
            diagram.findNodesByExample({isGroup: true}).each(group => {
                const picture =  group.findObject('pictureNode')
                picture.redraw()
                picture.reloadSource()
                console.log('Redrawing', picture)
            })
        }, null)

With my group template being:

 new go.Group('Auto', {
        ...
    })
        .bind(new go.Binding('location', 'coordinates', go.Point.parse))
        .add(new go.Picture({
            name: 'pictureNode'
        }).bind('source', 'placeholderImage'))

In my simplistic testing, it seems to work as expected. I wonder if your server has some caching policy that is preventing it from fetching the new image. You could force this client side by adding a fetch:

      diagram.commit(function (d) {
        diagram.findNodesByExample({ isGroup: true }).each(group => {
          const picture = group.findObject('pictureNode')
          picture.redraw()
          fetch(picture.source, { cache: 'reload', mode: 'no-cors' }); // force cache
          picture.reloadSource()
          console.log('Redrawing', picture)
        })
      }, null)

Which we could add to the library, though I am wary of unintended consequences in doing so for all customers.

Can you clarify how the internals of reloadSource work?
That’s pretty much what i assumed it did, fetch the url. Which is why i was expecting to see something in my network log. I fail to comprehend how it can reload a source without fetching it :-D
At first i thought it was a cache issue, but shouldn’t i at least see in my network inspector a request go out, but have it flagged as ‘cached’?

I also don’t have any specific caching rules on the resource in place, the headers of the request don’t mention any cache policy, so i assume it’s default.
I use azure blob storage. Here is a test link if you are wondering:

https://weavely.blob.core.windows.net/development-c72187d8-16eb-452f-9252-a2d8ee623185/66046770-4024-4000-a272-368158925000.jpg

When you set an Picture.source, we create a backing HTMLImageElement. When you call reloadSource, we clear that HTMLImageElement out of our cache so that the next time source is set, we create one again. Then reloadSource sets the source to the empty string, then to the url, forcing the creation of a new HTMLImageElement with its src set.

Now what the browser does in response to those events is… apparently, not necessarily even a single request. And apparently (and I should have thought of this) different when one has developer tools open, since I tend to have “disable cache” set. So it works when there’s no caching, but may not work in some more common cases.

We never use fetch in the library (or XMLHttpRequest), and I would prefer that the library contains no such calls, but one may be warranted here. We’ll have to think about it. Or we may have to mention it in the reloadSource documentation, at a minimum.

One simple change we could make is setting the Picture.source instead to the old source plus a query like ?t= ...some timestamp, to force a reload that way, but that may interfere with customers using params for their own purposes.

Well in my case there is no way around doing a new request, so if it is by calling fetch myself thats fine. Just assumed that’s what reloadSource did for me.

You could always add an optional argument to reloadSource to force a new fetch. Or document in the API what is needed for it to work (e.g. does it only work if the initial request has some specific cache policy?). Still not sure if i understand how it can work at all if the browser doesn’t do much in the case you describe.

Thanks for the help.

Yes sorry for the confusion. We’ll add it to the documentation for the method, at least. I’m still wary of adding it to the library itself though it’s probably right thing thing to be doing by default.