updateData partial update and drillThrough edit

Closed
Sophie L asked on December 9, 2021

Hello,
I'm trying to use Flexmonster to visualize and update some data through the drillthrough view by setting the editing: true configuration.

  1. If not using datachanged event to update data, the data seems to be updated, but with some problems. => If changing assignee for Task001 from A to B, the pivot table shows B twice
  2. If using datachanged callback to update data manually (in conjunction with updateData), things seem to partially work:
    • The selected field is updated, but if the drillThrough view contained a following item, datachanged is triggered a second time and updates 2 records (when I only wanted to update one)
    • As in case 1, the pivot gets updated but some lines get somehow duplicated
    • https://jsfiddle.net/soso/a75v1e8k/400/
    • I tried to build a simpler example to illustrate, but eventually, I would like to update other records when one is modified. So using datachanged/updateData seems the way to go.
  3. As a bonus, I'd like to be able if possible to only let one particular field be updated (the "Assignee"). I know the question has been raised a couple of times already but I'm not sure what the final status is on that issue.

I tried to follow instructions from:

Hope my example is clear enough.
(For more context: the idea is to view and balance the workload of different users)

8 answers

Public
Vera Didenko Vera Didenko Flexmonster December 10, 2021

Hello, Sophie,
 
Thank you for reaching out to us and for providing examples.
 
When a cell value is edited through Flexmonster, the changes are kept in memory and are not applied to the data set. With this in mind, checking the cell value on the datachanged event, applying the necessary changes to your data set, and using the updateData() API call to refresh the data in Flexmonster is the recommended way. As for updating only one particular field instead of the whole record, currently, all fields of the record need to be provided.
 
However, there seems to be an issue with the editing feature. Our team will need some time to investigate this case in more detail and we will share the results with the ETA 11th of January.
 
Please let us know if this would work fine for you. In the meantime, feel free to contact us if any questions arise.
 
Kind regards,
Vera

Public
Sophie L December 10, 2021

Hello, thanks for your reply.
I think I have a rough understanding by now of how things work.
However, I'd like to point out some inconsistent behaviours, as illustrated in the following http://jsfiddle.net/soso/ewunc4pf:

  1. Basic editing in the drillThrough is reflected in the main pivot table, but not in the report's dataSource. Let's say I change the colour from red to pink, I see pink displayed in the main pivot, but getReport().dataSource.data remains unchanged. As a result, if I click on the main "Save" button, the entry is not modified and I still get "red".
  2. If editing through updateData() API upon receiving the datachanged event, it seems that:
    1. calling updateData() API results in a new entry being added to getReport().dataSource.data. So again if save the report, I will get a json containing several entries with the same RowId. 
    2. I need to provide the full record and not only the changeset (unless I'm mistaken?). Given that getReport().dataSource.data may not be a reliable source of information, how can I retrieve the **up to date** report information? (I tried flexmonster.getData(), but it seems it's disabled in jsfiddle "trial" version, and besides, getData() returns the pivot information in a format that is not super friendly.

So right now, the solution I came up with is:

  1. disable drillThrough and set editable to false
  2. implement my own popup, with my own (non flexmonster) editable table solution
  3. call updateData with changeset from my custom popup/table
    • before updating data, search for the last version of RowId in my "source of truth" (getReport().dataSource.data) to retrieve current up to date record, update that record with the changeset, then call updateData([{ ...record, [field]: value, version: record.version+1 }], { partial: true}) - The version may not be necessary but I couldn't be certain that most up to date version would be the last entry in dataSource.data

That doesn't seem like the most efficient approach. So my follow-up questions would be:

  1. How can I retrieve my source of truth for the data (getReport().dataSource.data is simple, but hacky)
  2. Could updateData() and editable: true behave consistently?
  3. Is there an easy way to use a flexmonster table in my custom popup instead of another "table" solution?

To answer your question, with my current workaround, I don't need an immediate fix, but definitely any help or fix will be appreciated.

Public
Vera Didenko Vera Didenko Flexmonster December 13, 2021

Hello, Sophie,
 
Thank you for your reply.

As for basic editing in the drill-through being reflected in the main pivot table but not in the report's dataSource:
Our team would like to confirm that this is the expected behavior. Flexmonster is designed for analyzing and visualizing existing data; therefore, it is not intended for Flexmonster to edit the underlying data set. Still, Flexmonster offers a broad API reference allowing to implement an editing feature/scenario around Flexmonster.

Regarding the remaining points, please see our answers and suggestions below:
 

  1. Is there an easy way to use a flexmonster table in my custom popup instead of another "table" solution?

    Yes, in your custom popup, you could display a second Flexmonster instance using the flat layout. Aside from editing cells in the drill-through view, you can also edit cells directly on the grid in the flat layout.

    With this in mind, our team suggests the following approach for implementing the edit feature:

    Step 1: Disable the editing option and the drill-through view on the main pivot table.
    Step 2: When a grid cell is double-clicked, display a second Flexmonster instance in flat form in your own custom popup with the editing option enabled. We will use this Flexmonster instance for editing the data.

    This leads us to your next question: "How can I retrieve my source of truth for the data (getReport().dataSource.data is simple but hacky)".

    As mentioned in the beginning, Flexmonster is not designed for editing the underlying data set since it focuses on analyzing and visualizing existing data.
    Therefore, for your case, we recommend using the updateData() API call only for reloading the data in Flexmonster from your server (once the data set is updated on your server). Our team suggests the following solution for applying the changes to the data set:

    Step 3: Attach a handler for the datachanged event to the second Flexmonster instance (the one inside your custom popup from Step 2).
    Step 4: Once the datachanged event fires, apply the change to your data set outside of Flexmonster (for example, on your server).
    Step 5: After the change is applied in your data set (on your server), reload the updated data set from your server in Flexmonster with the updateData() API call (without the partial option) to reflect the changes.

  2. Could updateData() and editable: true behave consistently?

    It seems the root cause of the issue you are facing is the issue with duplicating tuples. If tuples are not repeated, the editable: true option and the datachanged event should work correctly and, as a result, this will remove the need for the second Flexmonster instance (in the custom pop-up). Our team is currently working on a solution for this issue, and we will return to you with updates with the ETA 11th of January.

We hope this helps. You are welcome to contact us if further questions arise.
 
Kind regards,
Vera

Public
Vera Didenko Vera Didenko Flexmonster January 11, 2022

Hello, Sophie,
 
We are happy to inform you that our team fixed the drillThrough edit inconsistencies. Now the issue with duplicate tuples when using the editing feature is fixed. Also, the issue with the unnecessary "datachanged" event triggering was fixed, so now the "datachanged" event will trigger only once when a record is edited.
 
This is available in the latest (2.9.16) minor release version of Flexmonster.
You are welcome to update the component. Here is our updating to the latest release version guide for assistance: https://www.flexmonster.com/doc/updating-to-the-latest-version/.
 
Please let us know if the fix works well for you.
 
Kind regards,
Vera

Public
Vera Didenko Vera Didenko Flexmonster January 25, 2022

Hello, Sophie,
 
Hope you're having a great week!
 
Just checking in to ask if you've had a chance to test out the mentioned fix. Is everything working well on your side?
 
We'd be happy to hear your feedback.
 
Kind regards,
Vera

Public
Sophie L January 25, 2022

Hello Vera,
I was able to verify (in one of my submitted fiddles http://jsfiddle.net/soso/ewunc4pf) that datachanged event now seems to trigger correctly.
I didn't test things too thoroughly though, as in the final implementation (React) I went with an alternate editing table, and I am managing the reference data in a React state (outside of Flexmonster, as you suggested).
Still, I think the fact that editable: true and partial update (which I didn't use in the end) could deserve some precisions in the documentation, since, for instance, we don't know what the "Save report" button will actually save (unless we keep track of changes externally and call a full updateData before saving the report to disk)
 

Public
Vera Didenko Vera Didenko Flexmonster January 26, 2022

Hello, Sophie,
 
Thank you for the update.
 
We are happy to hear that the datachanged event is working well and that the solution with an alternate editing table worked for you.
Regarding the editable: true usage details with calling updateData(), thank you for your feedback. Our documentation team will consider it in our documentation updates and improvements.
 
As always, should any questions arise, feel free to reach out to us.
 
Kind regards,
Vera

Public
Sophie L February 2, 2022

Hello again, I wasn't sure if I should open another ticket or stay in the new one, but I decided to post another problem I found, as it's related.
I implemented the logic discussed above in our real application which uses React.
Upon changing the reference data in a parent component, the data is updated in Flexmonster.
But whenever the data is changed, we're getting the following error from Flexmonster in the developer console: 

Uncaught TypeError: Cannot read properties of null (reading 'element')
at new k (flexmonster.full.js:99:1)
at h.Fe (flexmonster.full.js:1572:1)
at flexmonster.full.js:1561:1
k @ flexmonster.full.js:99
Fe @ flexmonster.full.js:1572
(anonyme) @ flexmonster.full.js:1561
requestAnimationFrame (asynchrone)
requestAnimationFrame @ flexmonster.full.js:149
u.$n.load.ON @ flexmonster.full.js:1559
load @ flexmonster.full.js:86
h @ flexmonster.full.js:1559
k @ flexmonster.full.js:2365
PivotApi @ flexmonster.full.js:2383
(anonyme) @ flexmonster.full.js:2393
(anonyme) @ index.js:1
invokePassiveEffectCreate @ react-dom.development.js:23487
callCallback @ react-dom.development.js:3945
invokeGuardedCallbackDev @ react-dom.development.js:3994
invokeGuardedCallback @ react-dom.development.js:4056
flushPassiveEffectsImpl @ react-dom.development.js:23574
unstable_runWithPriority @ scheduler.development.js:468
runWithPriority$1 @ react-dom.development.js:11276
flushPassiveEffects @ react-dom.development.js:23447
(anonyme) @ react-dom.development.js:23324
workLoop @ scheduler.development.js:417
flushWork @ scheduler.development.js:390
performWorkUntilDeadline @ scheduler.development.js:157

The implementation of the component looks roughly as below (the actual code is more complex).
The code is actually more complex, and may contain errors, but my first question here would be more to know how to debug the problem on my side. And to find out if this 

import React, { useEffect, useRef, useState } from 'react';
import { FlexmonsterReference, Pivot } from 'react-flexmonster/hooks';

// Illustration - Actual code may differ
const MyComponent: React.FC<any> = ({
licenseKey,
data,
config,
localization,
}) => {
const flexmonsterRef = useRef<FlexmonsterReference>(null);
const [report, setReport] = useState<any>([]);

useEffect(() => {
const x = {
...config,
localization,
dataSource: { data },
}
setReport(x);
}, [data, config, localization]);

// none of these are triggered
const handleDataError = (params: any) => console.log('dataerror', params);
const handleLocalizationError = () => console.log('localizationerror');
const handleQueryError = () => console.log('queryerror');

return (
<Pivot
ref={flexmonsterRef}
licenseKey={licenseKey}
report={report}
dataerror={handleDataError}
localizationerror={handleLocalizationError}
queryerror={handleQueryError}
/>
);
};

 
 

Tanya Gryshko created a new ticket #44105 from this answer

This question is now closed