Giter VIP home page Giter VIP logo

Comments (8)

benelliott avatar benelliott commented on September 26, 2024 1

I am not OP, but found this issue after running into similar limitations of the afterNextRender hook.

I was trying to use it inside an observable subscription, to update the scroll position of a container after Angular has written the contents of the observable back to the DOM.

I can't immediately invoke methods on the native DOM element to update its scroll position in the subscription because Angular obviously won't have re-rendered the element contents yet. I was hoping afterNextRender would help me avoid an ugly setTimeout-style hack to work around this.

Even though the observable itself is initialised in the component constructor, calling it inside the subscribe block throws an injection context error, which is unfortunate. This can be fixed via runInInjectionContext, but the code ends up quite hard to read:

myObservable$
.pipe(takeUntilDestroyed())
.subscribe(() => runInInjectionContext(this.environmentInjector, () => afterNextRender(() => this.doSomethingToTheDom())));

It would be nice if the afterNextRender docs could be fleshed out more to explain limitations and workarounds such as these. (Even nicer would be if some syntactic sugar could be used to hide the injection context stuff above!)

Alternatively, if I've completely misunderstood the point of afterNextRender and shouldn't be doing this with it, then some documentation to that effect would helpful too.

from angular.

JoostK avatar JoostK commented on September 26, 2024 1

AfterRenderOptions#injector showing as deprecated is a bug in the documentation, it is not marked as such in the source (/cc @JeanMeche)

from angular.

alxhub avatar alxhub commented on September 26, 2024

Hi,

Can you provide some context on what exactly you think is missing, besides documentation of the requirement for injection context?

from angular.

JoostK avatar JoostK commented on September 26, 2024

@benelliott if you can replace the observable with a signal, the new afterRenderEffect should help make this more ergonomic:

afterRenderEffect({
  write: () => this.doSomethingToTheDom(),
});

Here, any signal that is read in this.doSomethingToTheDom() will be considered a dependency of the DOM state, retriggering the DOM syncing on change, scheduled at an appropriate time w.r.t. rendering/change detection.

from angular.

JoostK avatar JoostK commented on September 26, 2024

Or with an observable, I suppose something along the lines of the following could work:

const signal = toSignal(myObservable$);

afterRenderEffect({
  write: () => this.doSomethingToTheDom(signal()),
});

If done in the constructor this follows the lifecycle of the component, destroying the observable subscription (that drives the signal) and the render effect as expected.

from angular.

kemsky avatar kemsky commented on September 26, 2024

@JoostK, the one and only thing that afterNextRender is supposed to do is to schedule callback to execute after next render (or render phase), it should not matter how, when, where it was triggered. Current implementation for some unknown reason was optimized to work in component constructor, it requires context (implicit or explicit). It is not documented what context can be supplied to this function, why and what will be consequences. Also, it is not specified how this works related to zones. afterNextRender simply can not be used in production code until these questions get answered.

Adding signals to this mess will only further complicate logic, introduce new hidden effects, timing issues and so on.

from angular.

kemsky avatar kemsky commented on September 26, 2024

injector property of AfterRenderOptions is marked as deprecated, so now I have no idea how this function is even supposed to be used.

from angular.

JeanMeche avatar JeanMeche commented on September 26, 2024

We have a pending PR that fixes this : #57595

from angular.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.