-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
fix(angular-query): fix NG0602 error #6966
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 1 Ignored Deployment
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 8107437:
|
☁️ Nx Cloud ReportCI is running/has finished running commands for commit 8107437. As they complete they will appear below. Click to see the status, the terminal output, and the build insights. 📂 See all runs for this CI Pipeline Execution ✅ Successfully ran 2 targetsSent with 💌 from NxCloud. |
Thank you @riccardoperra !
Did not look into it more than this video but nested effects should work in Angular. Although I'm not sure this could offer a solution as an effect is scheduled too late probably. I am interested in how you would solve it. What is your opinion on the lazy init proxy? Last week I was working a few evenings on replacing it with more computed() signals but it would require unpure computed signals and not sure if that would be better than the proxy. I would love to brainstorm about this with someone with good insight in signals.
Not really, good call to use queueMicrotask instead.
Agree, ran into this too. |
In that case I usually create an effect immediately that listen for an Did some test yesterday but probably I was doing something wrong. Today I managed to do it using // could be a boolean, or maybe a function to call lazily which uses signals internally
const ready = signal<boolean>(false);
const injector = inject(Injector);
const initEffect = effect(() => {
const isReady = ready();
if (!isReady) {
return;
}
// destroying the init effect in order to be sure it's immediately
// disposed after the first time
initEffect.destroy();
untracked(() =>
effect(
() => {
// call something that will use signals, input signals etc.
},
// we need to pass injector because we are outside the "constructor" phase
{ injector }
)
);
});
queueMicrotask(() => ready.set(true));
Unlike other frameworks, inputs are not immediately available. Unpure computeds are a bad practice, using that lazy init with a proxy could be a great option, I can't think of any other solutions that doesn’t prevent errors..even if there are some particular cases that don't convince me.
It therefore occurs to me that the result of the query is not directly accessible from the constructor, but must necessarily be executed in a reactive context such as an effect, or after onInit. So regardless we should prevent the access in this case...after all, those who develop in Angular know that certain things cannot be done in the constructor, especially if it uses inputs. return new Proxy<T>({} as T, {
get(_, prop, receiver) {
if (!initialized) {
// throw some understable error
}
// do something
},
} EDIT: this probably can't work anyway, because if the query is created inside the onInit there is a risk that the value will be inaccessible anyway. It's not possible to intercept the time after the constructor but before the template execution I think |
This pr fixes the NG0602 error while using angular-query.
Since the latest update, consuming the signals inside the templates caused to log the error.
Wrapping the effect inside the
untracked
function, in combination torunInInjectionContext
at the top level (which is already present), seems resolving the issue without preventing the effect from running without registering dependencies. The effect as I understood must be executed whenever thedefaultedOptionsSignal
changes, therefore the behavior would remain unchanged.I'm relatively new to Angular signals, I have much more experience using solid-js ones. Personally I would have solved it using nested effects but I think angular does not support them, like tracking dependencies after the first run 🤔
Also, I changed the Promise.resolve.then() using
queueMicrotask
. I think it is more suitable in this case. Is there a particular reason why Promise.resolve was used?PS.
While debugging using the angular query examples, I had some troubles to get the updated code after building the library. I just had to disable the ng cache in order to let it work..I think this should be a default option for that repo examples
@arnoud-dv