locked
File query contentschanged event not fired

    Question

  • Using this code, the contentschanged event is never fired:

    var changed, folder, options, query;

    folder = Windows.Storage.ApplicationData.current.localFolder; options = new Windows.Storage.Search.QueryOptions(Windows.Storage.Search.CommonFileQuery.orderBySearchRank, ["*"]); query = folder.createFileQueryWithOptions(options); changed = false; query.addEventListener("contentschanged", function(event) { return changed = true; }); WinJS.Application.local.writeText("watched file", "The Dude Abides!");


    The event is also not fired if I just create the file query without any options.

    edit: it seems the event is only fired after query.getFilesAsync has been called at least once. Is that by design?
    • Edited by phil_ke Tuesday, May 29, 2012 3:00 PM
    Tuesday, May 29, 2012 2:47 PM

All replies

  • Hi Phil,

    createFileQueryWithOptions loads up the query but you don't get wired up until you to getFilesAsync (or getFoldersAsync)


    Jeff Sanders (MSFT)

    Tuesday, May 29, 2012 6:42 PM
    Moderator
  • Yes, this should be stated in the docs though. Its not clear otherwise how the notifications come in.

    Do you know how they are implemented? They seem to have a rather big delay (1 sec) between the change happening and the notification to the listeners. Are they using FindFirstChangeNotification APIs under the hood?

    Wednesday, May 30, 2012 8:14 AM
  • Hi,

    I ran into the same issue (a call to getFilesAsync() being required for events to be fired). However, in my case, I still cannot register an event handler reliably -- one time it works and I get all the events for a query, while another time it doesn't and I do not get any events.

    It always works when I put breakpoints in the code, both an the point of the event registration as well as into the event handler function. If I just output something to console, I see that the handler is always registered, but sometimes it is not called. Do you have any idea what might go wrong? Do I have to take measures to keep the StorageFileQueryResult "alive", so that it isn't garbage-collected?

    This is my code:

        var fileQueryResults, queryOptions;
        queryOptions = new Windows.Storage.Search.QueryOptions();
        queryOptions.userSearchFilter = "System.FileName:=\"" + filename + "\"";
        fileQueryResults = folder.createFileQueryWithOptions(queryOptions);
        return fileQueryResults.getFilesAsync().then(function(files) {
          return fileQueryResults.addEventListener('contentschanged', function(event) {
            return doStuff();
          });
        });
    

    Thanks!

    Friday, August 24, 2012 1:44 PM
  • Hi G,

    Create a global object in your JavaScript instead of in the function.  That will keep it alive.

    -Jeff


    Jeff Sanders (MSFT)

    Friday, August 24, 2012 1:54 PM
    Moderator
  • gdoo,

    I am having the same problem, did you ever get an answer?

    Me when contentschanged is not firing:

    Sunday, December 23, 2012 9:30 AM
  • This is still current, yes. I'm just tearing my hear trying to debug this.

    I wrote a unit test which registers a 'contentschanged' listener on a StorageFileQueryResult obtained from a folder, copies a file into that folder, calls WinJS.Promise.timeout(12000) and then checks if the listener has been fired in the meantime.

    Bottom line is: sometimes it was, sometimes it wasn't. Especially when setting a breakpoint, it will succeed more often than fail but otherwise there's big randomness in there. I'm not very fond of the idea to further increase the timeout beyond 12 seconds because not only will that make the test suite run much longer but also because that won't feel very snappy for the user of the real app.

    12 seconds is like an eternity of nothing happening, the system is idle in all regards and every other filesystem API I know (including Windows 7 and before) will process change events faster than that.

    So: what's happening here?

    All the best
    Marcus

    Edit: I found that adding WinJS.Promise.timeout(1000) between registering the listener and copying the file will drastically improve the chances of getting a change event. Note that I always call getFilesAsync(), too, but that doesn't make a difference. Strange enough, sometimes I even get two events, maybe because copyFileAsync updates the last access timestamp on the file which triggers an event?

    Tuesday, January 8, 2013 3:16 PM
  • getFilesAsync is called, as edited into my initial question. However even with the query hold in a global var the change event is not triggered every time, and sometimes twice for file copy/modify actions.
    Tuesday, January 8, 2013 9:59 PM
    • Edited by Ben Kol Thursday, January 10, 2013 4:12 PM
    Thursday, January 10, 2013 4:11 PM