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

AsyncDirectives prevent mobx observables retriggering update #164

Open
benjamind opened this issue Apr 20, 2023 · 3 comments
Open

AsyncDirectives prevent mobx observables retriggering update #164

benjamind opened this issue Apr 20, 2023 · 3 comments

Comments

@benjamind
Copy link
Contributor

Expected Behaviour

Using async directives should 'just work' with the rendering component updating whenever an observable inside of the async directive is updated. The async directive of course should do what it always does.

Actual Behaviour

Mobx observables are not tracked within the callbacks of renders invoked by async directives like when and until.

Couple of possible approaches to fixing/workaround this:

  • Wrap all async directive render functions with helper functions to track the invocations and re-render the hosting component
  • Never use mobx observables directly in async directive render functions and instead always pass down the observable to a MobxLitElement that itself handles the re-render.
  • Extend Lits ReactiveElement with new hooks that are driven by AsyncDirective calls to setValue within their render tree. This is a much bigger change at the core of the library and would likely need updates to the AsyncDirective API.
@dnsflnv
Copy link

dnsflnv commented Dec 19, 2023

Use runInAction() in async.

    @action
    async deleteComment(id: number): Promise<void> {
        try {
            await api.delete(`comments/${id}`);
        } catch (error) {
            console.error(error);

            return;
        }

        const changedCommentThreads = { ...this.commentThreads };

        changedCommentThreads.data[id] = null;
        runInAction(() => {
            this.commentThreads = { ...changedCommentThreads };
        });
    }

@benjamind
Copy link
Contributor Author

Not quite the same thing, thats an async action. In an async directive like asyncAppend that will invoke the template and update the DOM in an asynchronous callback that is outside of the reaction that is being used to capture template usage of mobx observables. Therefore observables inside of the asyncAppend callback will not cause further updates to the template. This can be quite surprising given the magic that happens elsewhere.

@kamathln
Copy link

kamathln commented May 8, 2024

Thanks a lot Benjamin, I was about to lose my mind.

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

No branches or pull requests

3 participants