Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Is there a danger to override ResultSet.willFetchData ?

    We recently upgraded from 8.3 to 9.0p.

    We have a class wrapping a ListGrid that we use everywhere in our app.

    One of its methods is the following:
    Code:
    	//----------------------------------------------------------------------------------------------------------------------------
    	fetchData : function(criteria, callback, invalidateCache)
    	{
    		if (this.listGrid)
    		{
    			this.hideRecordFeedback();
    
    			if (true === invalidateCache)
    			{
    				// Caller wants us to force a request to the server.
    				// Reference : http://forums.smartclient.com/showthread.php?p=19915#post19915
    				if (isc.isA.ResultSet(this.listGrid.data)){
    					this.listGrid.data.invalidateCache();
    				}
    			}
    
    			this.listGrid.fetchData(criteria, callback, { showPrompt : true, prompt : OurStrings.get('global.list.loadingMessage') });
    		}
    	}
    We added that method because we needed the client to force a fetch to the back-end (even if the end user would not change any search fields of a dynamic form, we wanted the fetch to go back to the server in case the server contained new data matching the user's selection)

    Now, with the upgrade to 9.0; our wrapping is broken.

    We already posted on the forum here: http://forums.smartclient.com/showthread.php?p=114028 (we'll be replying to this other thread soon; my colleague is on vacation).

    We read a bit more on the new documentation that came with 9.0 and discovered that willFetchData() exists for a few modules.

    Our framework already has a "customization file" that contains the following:
    Code:
    BaseResultSet.addProperties
    ({
    	useClientFiltering : false,
    	useClientSorting : false
    });
    We're contemplating adding the following to it as another property:
    Code:
    	//--------------------------------------------------------------------------------------------------------------------------------
    	willFetchData : function(newCriteria, textMatchStyle)
    	{
    		return true;
    	}
    We do not care about the round-trips to the back-end because we want to make sure the user always works with the latest data from the server.

    What are the risks of doing so ? Are there any risks ?

    Thanks !

    SmartClient Version: v9.0p_2013-12-03/Pro Deployment (built 2013-12-03)

    #2
    It's not clear how broadly you are attempting to apply these settings, since you have a class "BaseResultSet" which is not a framework class.

    If you tried to change the default settings for useClientFiltering/useClientSorting or replace resultSet.willFetchData() on isc.ResultSet via isc.ResultSet.addProperties(), this would be invalid. Other code in the framework will assume that framework defaults are unchanged; the only exception is skinning-related properties.

    Secondarily, resultSet.willFetchData() does not doc any details of how or when it is called or used, it only describes what values it will return, a very different thing. Overriding it puts you into the area of undefined behavior, and you don't actually appear to have a reason to attempt this override. You should just be focused on the other thread where we are trying to help you determine what's gone wrong with your previous approach.

    Comment


      #3
      Is there a danger to override ResultSet.willFetchData ?

      Originally posted by Isomorphic View Post
      If you tried to change the default settings for useClientFiltering/useClientSorting or replace resultSet.willFetchData() on isc.ResultSet via isc.ResultSet.addProperties(), this would be invalid. Other code in the framework will assume that framework defaults are unchanged; the only exception is skinning-related properties.
      You got me worried with what you wrote and I want to clarify the situation.

      We defined the following:
      Code:
      //--------------------------------------------------------------------------------------------------------------------------------
      var BaseResultSet = isc.defineClass('BaseResultSet', 'ResultSet');
      
      //-----------------------------
      // Instance class members
      //-----------------------------
      BaseResultSet.addProperties
      ({
      	useClientFiltering : false,
      	useClientSorting : false
      });
      And then, we refer to BaseResultSet like this:
      Code:
      //--------------------------------------------------------------------------------------------------------------------------------
      var BaseDataSource = isc.defineClass('BaseDataSource', 'DataSource');
      
      BaseDataSource.addProperties
      ({
      	resultSetClass : 'BaseResultSet'
      });
      All our client-server interactions are done using BaseDataSource-derived classes.

      Why would this not work ?

      Thanks !

      Comment


        #4
        We can't point to a specific problem this would cause right now, but for example, if there were framework code that obtained a ResultSet from a DataSource and assumed it had normal behavior, and your customization below broke that code, this would not be considered a framework bug.

        A narrower customization of setting dataProperties just on the grids where you want zero caching would be safer.

        Overriding willFetchData() continues to be something we wouldn't recommend at all, for the previously stated reasons.

        Comment


          #5
          Thanks for the pointer on "dataProperties", we'll look into it and potentially get rid of our BaseResultSet class.

          2 questions:

          1. Based on what you wrote, how can we determine whether an attribute is related to "normal behavior" ? We assumed that as soon as an attribute was part of the doc, we could always safely override it. Is that not the case ?


          2. We appreciate your advice on not overriding willFetchData(). As I mentioned in my previous post about our use of invalidateCache():
          we needed the client to force a fetch to the back-end (even if the end user would not change any search fields of a dynamic form, we wanted the fetch to go back to the server in case the server contained new data matching the user's selection)
          What would be a possible solution to our problem ? We want a datasource GET request to always fire a call to the back-end. We want to implement a solution following your guidelines and make sure a future upgrade is flawless.

          More background info about our datasource operations (I don't know whether it matters, but I wanted to provide as much as possible):
          - we use paging on our data sources
          - our POST operations can either return a single or multiple records
          - our PUT operations return the the modified entity
          - our DELETE operations either return HTTP 204 for a success or a HTTP 400 when a problem occurs (wrong identifier for the record to delete, DBMS' referential integrity prevented the removal from occuring, etc).

          Thanks !

          Comment


            #6
            We assumed that as soon as an attribute was part of the doc, we could always safely override it. Is that not the case ?
            If you were creating a ResultSet and using it directly, you could safely use any attribute. What you're doing is changing the default setting for a DataSource being used by both framework components and your own components. Changing the default behavior of a low-level layer upon which other layers depend is likely to lead to faults in any software system.

            What would be a possible solution to our problem ? We want a datasource GET request to always fire a call to the back-end. We want to implement a solution following your guidelines and make sure a future upgrade is flawless.
            We already answered this - set useClientFiltering/useClientSorting via dataProperties so you are configuring just one grid.

            Comment


              #7
              I attempted to use "dataProperties" with "useClientFiltering = false" and "useClientSorting = false" and I didn't get the expected behavior:
              even with those attributes set to false, a call to ListGrid.fetchData() won't fire a request to the back-end.

              Do I need to provide a specific requestProperty to fetchData() ?

              I added screenshots from Chrome's Developer Tools when my ListGrid is instantiated; do you see something obvious I missed ? (Sorry for the separate files, but the forum's limit on image size and file size are quite low. I tried Log.echo(), but the content was truncated).

              I read, once more, documentation of ListGrid.fetchData() and paid attention to the block about invalidateCache(). I tried using only invalidateCache() (instead of calling invalidateCache() _and_ fetchData()), but my problem is invalidateCache() does NOT feature a callback parameter. I'm reluctant to directly call Class.fireCallback() right after calling invalidateCache() because I'd like the callback to be executed _after_ the invalidateCache-triggered-fetch (as if my code was following the original ListGrid.fetchData() path).

              Looking forward to hear back from you,

              Thanks in advance !
              Attached Files

              Comment


                #8
                Using dataProperties on ListGrid is exactly analogous to your previous attempt to use a "BaseResultSet" class. To get help with what went wrong, you need to show your code.

                If you use invalidateCache() to drop the current data, you can use the dataArrived event to find out when the data arrives from the server.

                Comment

                Working...
                X