I am trying to setup my auth.component.ts file to use ViewContainerRef from the placeholder.directive.ts file, but I am unsure what I need to populate inside the createComponent() at the end of the auth.component.ts file.
Below is the auth.component.ts file, with the original code using ComponentFactorResolver commented out at the bottom in the showErrorAlert method:
import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from "@angular/core";
import { NgForm } from "@angular/forms";
import { AuthService, AuthResponseData } from "./auth.service";
import { Observable } from "rxjs";
import { Router } from "@angular/router";
import { AlertComponent } from "../shared/alert/alert.component";
import { PlaceholderDirective } from "../shared/placeholder/placeholder.directive";
@Component({
selector: 'app-auth',
templateUrl: './auth.component.html'
})
export class AuthComponent {
isLoginMode = true;
isLoading = false;
error: string = null;
@ViewChild(PlaceholderDirective, { static: false}) alertHost: PlaceholderDirective;
constructor(
private authService: AuthService,
private router: Router,
private componentFactoryResolver: ComponentFactoryResolver,
private viewContainerRef: ViewContainerRef
) {}
onSwitchMode() {
this.isLoginMode = !this.isLoginMode
}
onSubmit(form: NgForm) {
if (!form.valid) {
return;
}
const email = form.value.email;
const password = form.value.password;
let authObs: Observable<AuthResponseData>;
this.isLoading = true;
if (this.isLoginMode) {
authObs = this.authService.login(email,password)
} else {
authObs = this.authService.signup(email,password)
}
authObs.subscribe(
resData => {
console.log(resData);
this.isLoading = false;
this.router.navigate(['/recipes']);
}, errorMessage => {
console.log(errorMessage);
this.error = errorMessage
this.showErrorAlert(errorMessage);
this.isLoading = false;
}
);
form.reset();
}
onHandleError() {
this.error = null;
}
private showErrorAlert(message: string) {
// const alertCmpFactory = this.componentFactoryResolver.resolveComponentFactory(AlertComponent);
// const alertCmpFactory = this.componentFactoryResolver.resolveComponentFactory(AlertComponent);
// const hostViewContainerRef = this.alertHost.viewContainerRef;
// hostViewContainerRef.clear();
// hostViewContainerRef.createComponent(alertCmpFactory);
const hostViewContainerRef = this.alertHost.viewContainerRef;
hostViewContainerRef.clear();
hostViewContainerRef.createComponent(hostViewContainerRef);
}
}
Below is the placeholder.directive.ts code:
import { Directive, ViewContainerRef } from "@angular/core";
@Directive({
selector: '[appPlaceholder]'
})
export class PlaceholderDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
I feel like I was able to get most of it converted over, but the line from auth.component.ts below I cannot figure out what should be the dynamic child component that was mentioned in another Stack Overflow question
Replace deprecated Angular ComponentFactoryResolver, ComponentFactory
hostViewContainerRef.createComponent(hostViewContainerRef);
Please let me know your thoughts. Thank you!
I tried following along with the post from here Replace deprecated Angular ComponentFactoryResolver, ComponentFactory
However, I am struggling to understand what "theYourDynamicChildComponent" or "YourElement" should be.
You can just render the component using createComponent
directly.
I think the references to "theYourDynamicChildComponent"
is to AlertComponent
.
The thing to note is that, if your component (AlertComponent
) is standalone then it's simpler to use. If your component is not standalone, then it might be needed to be added to the declarations array.
Also when you create the component and you notice the component does not work as expected, you can try adding environmentInjector
as a parameter to the createComponent(AlertComponent, {environmentInjector: environmentInjector});
Where the environment injector can be fetched using environmentInjector = inject(EnvironmentInjector);
.
const hostViewContainerRef = this.alertHost.viewContainerRef;
hostViewContainerRef.clear();
hostViewContainerRef.createComponent(AlertComponent);
If the component is rendered multiple times, you might get the error.