Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose setprops #2758

Merged
merged 24 commits into from
Feb 27, 2024
Merged

Expose setprops #2758

merged 24 commits into from
Feb 27, 2024

Conversation

BSd3v
Copy link
Contributor

@BSd3v BSd3v commented Feb 14, 2024

This PR is an attempt to expose the Dash components and renderer to be utilized by JS scripts/components by bringing the setProps to dash_clientside.setProps.

Contributor Checklist

  • I have broken down my PR scope into the following TODO tasks
    • expose setProps to dash_clientside.setProps
  • I have run the tests locally and they passed. (refer to testing section in contributing)
  • I have added tests, or extended existing tests, to cover any new features or bugs fixed in this PR

optionals

  • I have added entry in the CHANGELOG.md
  • If this PR needs a follow-up in dash docs, community thread, I have mentioned the relevant URLS as follows
    • this GitHub #PR number updates the dash docs
    • here is the show and tell thread in Plotly Dash community

@BSd3v BSd3v requested a review from alexcjohnson as a code owner February 14, 2024 03:34
notifyObservers({id: componentId, props})
);
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "observer" pattern in this redux context is very weird, it's meant to act as reducer with side effects.
I think this will be called on every callbacks and it should be only defined once. Maybe just move the definition on the window to store.ts in createApp instead would be better.

Copy link
Contributor Author

@BSd3v BSd3v Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Within this context (line 58 store.ts):

private createAppStore = (reducer: any, middleware: any) => {
        this.__store = createStore(reducer, middleware);
        this.storeObserver.setStore(this.__store);
        this.setObservers();
    };

Comment on lines 4 to 13
const set_props = (updates: []) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const ds = (window.dash_stores = window.dash_stores || []);
for (let y = 0; y < ds.length; y++) {
const {dispatch, getState} = ds[y];
const {paths} = getState();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
updates.forEach(({id, ...props}) => {
Copy link
Contributor

@T4rk1n T4rk1n Feb 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the api for this could be simpler without the batching of updates and extracting the id from the props into a function argument.
The function signature would then look like:

set_props(id: string | object, props: {[k: string]: any}): void;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, unless we would want to be able to send batches of updates and not trigger the renderer until the props have been updated?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For batching to work it needs a import {batch} from 'react-redux', or in react 18 it would be kinda automatic in effects and lifecycle methods. But it's only for calling within a react context, which might not always be the case here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, for this, it would be in the context of JS, however, I thought with the function coming from within the React lifecycle, this would still be a react response?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inside a clientside callback there is a react context, but since this is exposed globally it may be called from event handlers or anywhere really.
I think in the most simple cases it would be to update a single component like a toast message and multiple props on the component can still be set at once.
This API will also be implemented on the Python side for updating non output props inside callbacks, a simpler API will be better in that case and to make sure the id is provided.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, yeah, I can change it, was just thinking in general how the callbacks work with being able to pass multiple at the same time.

Comment on lines 5 to 7
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const ds = (window.dash_stores = window.dash_stores || []);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My TypeScript skills are pretty basic, but can't we avoid these comments (3 in this file and store.ts) with a few well-placed as any or some such? @T4rk1n you're better at this than I am, can you comment?

Copy link
Collaborator

@alexcjohnson alexcjohnson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💃 Very nice! If we can avoid those eslint/ts-ignore comment pairs that would be great, but I won't block the PR on that.

Love the test 😍

@alexcjohnson alexcjohnson merged commit 44cbee3 into plotly:dev Feb 27, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants