I'm using a simple directive to focus a text input when the element is active using *ngIf
. This is contained within a *ngFor
loop.
When the first *ngIf
is activated, the input focuses as expected. When another input is activated I get the error:
EXCEPTION: Attempt to use a dehydrated detector.
I don't understand what this means and how I can prevent the error. The functionality still works even with the error.
@Directive({
selector: '[myAutoFocus]'
})
export class AutoFocusDirective {
constructor(private elem: ElementRef) {
window.setTimeout(function() {
elem.nativeElement.querySelector('input').focus();
});
}
}
```
Dehydrated detector is a component that has been removed from the change detection system, usually because it has been unmounted from DOM by *ngIf
or other means:
If there's an asynchronous action in the application that hits this already unmounted detector, error is thrown:
solution is to use [hidden]
instead of *ngIf
on the affected component, or defer the offending action to next tick using setTimeout( () => this.offendingAction(), 0)
There is an open issue on GitHub for this: https://github.com/angular/angular/issues/6786#issuecomment-185429140
In beta.2, no exception was thrown. In beta.3-6 (4,5, and 6 seem to be just increments with no changes), the code was changed to throw an exception. You are correct that this currently does not pose an issue.
While I do not know the exact reason you receive this error, one of my accounts with it came from disposing of a component during the angular check cycle, where it updates views. Others have logged their issues on the github thread.
A "dehydrated detector" means that the change detector for that component/directive is no longer hydrated. (Sorry, I just couldn't resist -- I have no idea what this error means either, nor do I know what "hydrated" or "dehydrated" is supposed to convey.)
This source file says:
/**
* Thrown when change detector executes on dehydrated view.
*
* This error indicates a bug in the framework.
*
* This is an internal Angular error.
*/
export class DehydratedException extends BaseException {
constructor(details: string) { super(`Attempt to use a dehydrated detector: ${details}`); }
}
So you probably found an internal Angular bug.
I can't reproduce your error with this simple plunker. Do you have a plunker that shows the issue?
See also https://github.com/angular/angular/issues/6786
I have had this exception before and it very much means that you are using something that is no longer exists in the virtual memory. In my case, I was doing almost the same what you were doing. Notice you are trying to access an element after a timeout, but are you sure this element exists in the memory after this time is elapsed? I have *ngIf on that element and I accessed after the condition was false and it was already removed.