Opening dialog box through a service

956 views Asked by At

Here is the problem:

I have a nav bar having some nav options including login button which is situated in app.component.html

This is structure of AppComponent:

export class AppComponent {

logInDialogRef: MdDialogRef<LoginComponent>;

public constructor(public http: Http, private viewContainerRef: ViewContainerRef, 
          public dialog: MdDialog) {}

loginUser(){
    let config = new MdDialogConfig();
    config.viewContainerRef = this.viewContainerRef;
    config.role = 'dialog';
    config.width = '40%';
    this.logInDialogRef = this.dialog.open(LoginComponent, config);
}
}

When I click on login, I get nice pop up for login. I have another nav option which is protected route.

{path: 'products', component: ProductsComponent, canActivate: [AuthGuard]}

Suppose I am on some route say solutions. From here I login, I store jwt token in localstorage. Then I click on Products. Since user is logged in it should navigate or it should give pop up if no user is logged in.

But I'm getting nothing. Getting following error:

EXCEPTION: Uncaught (in promise): Error: No provider for ViewContainerRef!

CanActivate method of Auth.Guard.ts

canActivate() {
if (tokenNotExpired()) {
    return true;
}

this.loginService
    .loginUser(this.viewContainerRef)
    .subscribe(res => this.result = res);

return false;
}

LoginService have same loginUser method as above in app.component

app/login/login.service.ts

public loginUser(viewContainerRef: ViewContainerRef): Observable<any> {

    let dialogRef: MdDialogRef<LoginComponent>;
    let config = new MdDialogConfig();
    config.viewContainerRef = viewContainerRef;
    config.role = 'dialog';
    config.width = '40%';
    dialogRef = this.dialog.open(LoginComponent, config);
    return dialogRef.afterClosed();
}

I hope information is clear. Please tell if further clarification is needed.

The problem is opening dialog from different component through a service while same can be done from individual component easily i.e. app.component in this case.

1

There are 1 answers

1
yurzui On

You can try the following:

Auth.Guard.ts

@Injectable()
export class AuthGuard implements CanActivate {
  viewContainerRef: ViewContainerRef;
  constructor(private appRef: ApplicationRef) {
    this.viewContainerRef = appRef.components[0].instance.viewContainerRef;
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    ...
  }
}

Check also my Plunker Example (There is used lazy loading for ProductsModule)