4

I'm updating my angular2 application to RC.7 and I've hit a snag with my guard that checks a user permission before allowing access to the page. Right now I've simplified the guard to just return true always and it's still not working - looks like it can't find my appStateService, but I have injected it into other components and services in my app and it works ok there.

Guard Code:

import { Inject, Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

import { AppStateService } from '../../appState';

@Injectable()
export class MonitorPermissionGuard implements CanActivate {

constructor(private appStateService: AppStateService, private router: Router) {}

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    console.log('guard called');
    return true;
}

}

My app.module.ts file has both the AppStateService and the MonitorPermissionGuard added to the providers array.

I get the following error in my console when I run the app:

metadata_resolver.js:523 Uncaught Error: Can't resolve all parameters for MonitorPermissionGuard: (?, Router).

Not sure whats going on here because I've used the appStateService throughout the app with no problems.

Thanks

EDIT: Code for AppStateService

@Injectable()
export class AppStateService {

public appState: AppStateModel;

constructor() {
    this.appState = new AppStateModel();
}

toggleSidenav() {
    this.appState.sidenavExpand = !this.appState.sidenavExpand;
}

clearSidenav() {
    this.appState.sidenavButtons = new Array<SidenavButton>();
}

addSidenavLink(buttonText: string, iconClass: string, route: string) {
    let sidenavButton: SidenavButton = new SidenavButton(buttonText, iconClass, route);
    this.appState.sidenavButtons.push(sidenavButton);
}

setPageTitle(pageTitle: string) {
    this.appState.pageTitle = pageTitle;
}

hasPermission(feature: string) {
    return this.appState.userPermissions[feature];
}

giveFeaturePermission(feature: string) {
    this.appState.userPermissions[feature] = true;
}

recantFeaturePermission(feature: string) {
    this.appState.userPermissions[feature] = false;
}

showInfo(message: string) {
    this.showMessage('INFO', message);
}

showWarning(message: string) {
    this.showMessage('WARNING', message);
}

showError(message: string) {
    this.showMessage('ERROR', message);
}

private showMessage(type: string, message: string) {
    this.appState.appMessage.type = type;
    this.appState.appMessage.message = message;
    this.appState.isMessageShown = true;
    setTimeout(() => { this.appState.isMessageShown = false; }, 2000);
}

}
peppermcknight
  • 1,545
  • 16
  • 30
  • Can you show us the AppStateService? Maybe something in that will point in the right direction? – Dave V Sep 14 '16 at 13:32
  • @DaveV edited the question with the code for the app state service – peppermcknight Sep 14 '16 at 13:34
  • 1
    I wonder if it's having problems with newing up the AppStateModel. Can you comment out the newing up of it in the constructor (you'll probably have to comment everything out, but maybe that will at least let it load as a test) – Dave V Sep 14 '16 at 13:36
  • 1
    @DaveV that was a good shout, I've commented out the internals of the appStateService and the code for one of the components that uses the guard referencing the appStateService missing methods and now the page is loading and the guard is being called correctly. Do you know of a quick way I can make this work - export the AppStateModel in my code (right now its just an internal model)? And do you know why it only breaks when I try to use the AppStateService in a guard, when I've used in in components and services before without issue? – peppermcknight Sep 14 '16 at 13:44
  • I do not actually know, I haven't had to do anything like that in my projects yet. I may play with this concept a bit to see if I can get a similar behavior, but I'm not sure why newing up the AppStateModel would fail, unless there's something in the AppStateModel that is breaking on the new. – Dave V Sep 14 '16 at 13:47
  • 1
    So I've played around with it a bit and I've found that its not actually the newing up of the AppStateModel thats causing this error to show, its one of the functions inside the appStateService. If I uncomment all but the addSidenavLink function then the guard instantiates and works properly, but this function breaks it - trying to investigate why this is happening – peppermcknight Sep 14 '16 at 14:24
  • Is it the pushing of the button into the collection or is it newing up the button that's breaking? – Dave V Sep 14 '16 at 14:25
  • 2
    @DaveV ok worked it out, its the creation of the SidenavButton thats causing this - if I'm to hazard a guess as to why this is its because my sidenav button model is located and exported from the shared/ folder, the same place that my guard is being exported from - this is creating a circular dependency from shared/**/MonitorPermissionGuard -> AppStateService -> shared/**/SidenavButton - just checked by removing my sidenavbutton from the shared folder and recrating it as an internal structure for the appstateservice (its only used in there anyway) and now the original code works. – peppermcknight Sep 14 '16 at 14:28
  • Sweet! Glad I could help out! – Dave V Sep 14 '16 at 14:34
  • I had the same issue and the answer [here](http://stackoverflow.com/questions/37997824/angular-2-di-error-exception-cant-resolve-all-parameters) helped out – Joseph muli Dec 18 '16 at 11:41

0 Answers0