Announcement

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

    Does updateData() require all fields to be populated?

    I am using a listgrid that has one of its fields with a summary function (via setSummaryFunction()). It is linked to a data source which has setClientOnly(true). I can add, remove and update full records fine using the addData(), removeData() and updateData() functions fine with the list grid displaying correctly.

    However, when I only populate only the values that have changed in a record and send that via updateData() to the data source, if I omit the field that corresponds to the field in the listgrid with the summary function, I found my code behaves as no value is present when the listgrid updates.

    While I could work around the problem I was assuming that updating the record in the data source would effectively merge the changed and unchanged values in the listgrid and the summary function would operate on the unchanged value when a refresh was triggered (rather than it believe it does not exist). I am now wondering if my understanding is actually incorrect and I have to send a full record even if some values are unchanged ...

    So before I adjust my code I thought I should check: Am I using updateData correctly? Should all fields in my record to updateData be filled even if they are not changed - especially ones that have a summary function on that field in the listgrid - even if they are unchanged? Updates seem to display correctly otherwise (even if only a single field is changed in the record).

    I am using SmartGWT LGPL 3.0.

    #2
    You only need to send the primaryKey and changed fields - you probably have a bug in your code. See also the FAQ on grids not updating automatically.

    Comment


      #3
      Thanks for clarifying. I have taken an example out of the "Grid summaries" example out of the Smartgwt showcase, simplified it by removing some fields from the listgrid and the datasource, and replaced the summary function to be similar to mine. I also have modified it by using setClientOnly(true) and am loading/updating data via addData/updateData.

      What my summary function (on the category field) tries to do is to only count the number of instances of a specific category (rather than the distinct number of categories like in the example). If I update the record so it has a different description when the summary function re-runs it gives a null pointer exception as the getAttribute("category") retrieves null and thus fails the comparison to the category string I am trying to count.

      I tried upgrading to the Smartgwt 3.1 but have found the same issue. I would have expected that if I update the data source with only a single field in a record, that the summary function would still be able to access the data in an unchanged field in that same record in the listgrid itself.

      Not sure if this is expected (your response seems to suggest that it is not). I am not sure how I can work around this looking at the available functions?

      Code is included below - thanks in advance ...

      Code:
      package com.missingmatter.testsummaries.client;
      		  
      import com.smartgwt.client.data.DataSource;  
      import com.smartgwt.client.data.Record;  
      import com.smartgwt.client.data.fields.DataSourceIntegerField;
      import com.smartgwt.client.data.fields.DataSourceSequenceField;
      import com.smartgwt.client.data.fields.DataSourceTextField;
      import com.smartgwt.client.types.GroupStartOpen;  
      import com.smartgwt.client.types.SummaryFunctionType;  
      import com.smartgwt.client.widgets.grid.*;   		  
      import com.google.gwt.core.client.EntryPoint;  
      
      public class Testsummaries implements EntryPoint
      {
      	DataSource dataSource = new DataSource();
      
      	public void onModuleLoad()
      	{
      		// Set up datasource
      
      		
      		dataSource.setID("orderItemLocalDS");  
              
              DataSourceSequenceField pkField = new DataSourceSequenceField("pk");  
              pkField.setHidden(true);  
              pkField.setPrimaryKey(true);  
        
              DataSourceIntegerField orderIdField = new DataSourceIntegerField("orderID", "Order ID");  
              orderIdField.setCanEdit(false);  
              orderIdField.setPluralTitle("Orders");  
        
              DataSourceTextField itemDescriptionField = new DataSourceTextField("itemDescription", "Description");  
              DataSourceTextField categoryField = new DataSourceTextField("category", "Category");  
      
              dataSource.setFields(pkField, orderIdField, itemDescriptionField, categoryField);
              
              dataSource.setClientOnly(true);
              
      		// Set up listgrid
      		ListGridField listGridOrderIdField = new ListGridField("orderID");  
      		listGridOrderIdField.setIncludeInRecordSummary(false);  
      		listGridOrderIdField.setSummaryFunction(SummaryFunctionType.COUNT);  
      
      		ListGridField listGridItemDescriptionField = new ListGridField("itemDescription");  
      
      		ListGridField listGridCategoryField = new ListGridField("category");  
      		listGridCategoryField.setShowGridSummary(true);  
      		listGridCategoryField.setSummaryFunction(new SummaryFunction()
      		{  
      			public Object getSummaryValue(Record[] p_Records, ListGridField p_Field)
      			{
      				long l_SoftwarePackages = 0;
              	
      				for (int l_Index = 0; l_Index < p_Records.length; l_Index++)
      				{  
      					Record l_Record = p_Records[l_Index];  
      					String l_RecordCategory = l_Record.getAttribute("category");
      					
      					if ( ( l_RecordCategory != null ) && ( l_RecordCategory.equals("Software") ) )
      					{
      						l_SoftwarePackages++;
      					}
      				}
                  
      				return l_SoftwarePackages + " Software packages";  
      			} 
      		});  
      		
      		final ListGrid listGrid = new ListGrid();  
      		  
      		listGrid.setWidth(600);  
      		listGrid.setHeight(520);  
      		listGrid.setAutoFetchData(true);  
      		  
      		listGrid.setShowAllRecords(true);  
      		listGrid.setDataSource(dataSource);  
      		listGrid.setCanEdit(true);  
      		listGrid.setGroupByField("category");  
      		listGrid.setGroupStartOpen(GroupStartOpen.ALL);   
      		listGrid.setShowGridSummary(true);  
      		listGrid.setShowGroupSummary(true);  
      		  
      		listGrid.setFields(listGridOrderIdField, listGridItemDescriptionField, listGridCategoryField);
      		
      		listGrid.draw();  
      		
      		// Add a record
      		Record recordToAdd = new Record();
      		recordToAdd.setAttribute("pk", 0);
      		recordToAdd.setAttribute("orderID", 8805);
      		recordToAdd.setAttribute("itemDescription", "Anti Virus Suite");
      		recordToAdd.setAttribute("category", "Software");
      		dataSource.addData(recordToAdd, new DSCallback()
      		{
      				      public void execute(DSResponse response, Object rawData, DSRequest request)
      				      {
      				  			// Update a record
      				  			Record recordToUpdate = new Record();
      				  			recordToUpdate.setAttribute("pk", 0);
      				  			recordToUpdate.setAttribute("itemDescription", "Security Suite");
      				  			dataSource.updateData(recordToUpdate);
      				      }
      		});
      	}  		  
      }
      Last edited by dsammut; 25 Mar 2012, 23:55.

      Comment


        #4
        Again, you need to see the FAQ on grids not updating. Most likely you are returning partial data from the server in your DSResponse for the update.

        Comment


          #5
          Apologies if I am mistunderstanding something but my listgrid is updating fine - the problem seems to be that the record provided to the summary function on the list grid field seems to contain just the fields that have been updated in the record, not the actually ones that are displayed by the listgrid (e.g. the merge of the update to the original record I added). I have already gone through the FAQ. Note that I am not using a DSresponse - the calls I am using don't seem to require one (? - see below)

          To summarise what I am doing:

          * setClientOnly(true)
          * On the listgrid I have a summary function that counts the number of instances in a particular state (or in this case category = Software)
          * I define a data source and the listgrid is linked to it - a primary key exists
          * I add a complete record via addData(record) to the data source - all fields in record are populated
          * I update a record via updateData(record) to the data source - only the primary key and the description is included in this update record (not the category field which has the summary function)

          There is only one record that is added in the code and the summary function shows that the record provided to it on the update does not have category set (even though it was set in the added record). The field that I updated on the list grid via updateData (the description field) is displaying the update correctly so updates are coming through ok ...

          The code provided in my previous post shows the problem. It is based on the "Grid summaries" example code in the showcase. I simplified it, cut it down to a single field and added my mods that show the problem to make it easy to replicate ...

          Thanks again for your help ...

          EDIT: Updated the code in the previous post to include a guard against comparing a null string - when the code is run you will notice that while there is a single record with a category of Software, the grid summary at the bottom right of the grid says 0 software packages when it should say 1 software packages.
          Last edited by dsammut; 24 Mar 2012, 21:33.

          Comment


            #6
            On DSResponse, read the QuickStart Guide, Data Integration chapter, and don't skip the section on cache sync and the ResultSet.

            As far as your test code, you're doing an add, which is an asynchronous operation, followed immediately by an update against a record which may not exist yet. To correct your code, perform the update only when you get a callback indicating the add has completed. To correct the problem in general with a real DataSource, again see the FAQ.

            Comment


              #7
              Thanks again for your response. I have made a quick modification to the program so that the update is called inside the callback for the addData and unfortunately the problem remains.

              As I am using addData/updateData/removeData calls I don't really have a DSResponse to work with. All the data in the grids are updating with data correctly so I do not believe I have any problem with my DataSource (I have read the FAQ).

              Example program aside, the real program I am writing uses gwteventservice and receives updates every 5 seconds so there are plenty of time between adds/updates to each record with only values that have changed being sent across. It experiences exactly the same fault.

              If there was a problem with with my program, what it does not explain is that fact that if the record given to updateData contains a change to the field with the summary function it is fine - if it does not contain a change to that field the value in the record returned to the summary function does not exist. This behaviour simply does not make sense.

              I have updated the code above again to reflect the changes I have made - the behaviour is pretty easy to reproduce. Not sure what else I can do to resolve it short of always sending the current value of any field with a custom summary function in an update from the server regardless of whether it has changed (which strangely means it works fine but sucks up bandwidth unnecessarily) - any help appreciated.
              Last edited by dsammut; 26 Mar 2012, 00:16.

              Comment


                #8
                We've found the cause of this and fixed it.
                Please try the next nightly build (3.0p) to see the fix. Let us know if it doesn't appear to be resolved in your real use case.

                Thanks
                Isomorphic Software

                Comment


                  #9
                  Thanks! - I will move over to it asap.

                  Comment


                    #10
                    Yes - the new version has resolved the problem. Thanks for your help!

                    Comment

                    Working...
                    X