Search code examples
angularobserver-patternsubjectsubject-observer

Can't resolve all parameters for Component: (?)


I've got an Error message, as the title says. I searched for a solution here but unfortunately @Injectable() is not working, since I'm working with interfaces , and I also tried @Input(). What I'm trying to do here is an Observer pattern, to get notified when something happens on a click.

I tried to copy this pattern from this video here: https://www.youtube.com/watch?v=GioexP_s5Yc . I checked my code several times, and it does not differ except that I use Angular and try to adapt this pattern between 2 components.

This is my setup:

observer.interface.ts

export interface Observer {
    update(fileName: string);
}

subject.interface.ts

import { Observer } from "./observer.interface";

export interface Subject {
    registerObserver(o: Observer);
    removeObserver(o: Observer);
    notifyObservers();
}

XComponent.ts

export class FileExplorerComponent implements OnInit, Subject {

  fileString: string;
  private observers: Observer[] = [];

  showFile(fileName) {
    this.fileString = fileName;
    this.notifyObservers();
  }

  public registerObserver(o: Observer) {
    this.observers.push(o);
  }

  public removeObserver(o: Observer) {
    let index = this.observers.indexOf(o);
    this.observers.splice(index, 1);
  }

  public notifyObservers() {
    for (let observer of this.observers) {
      observer.update(this.fileString);
    }
  }
}

YComponent.ts

import { Subject } from '../X/subject.interface';
import { Observer } from '../X/observer.interface';

export class JsonBuilderComponent implements Observer {

subject: Subject;

constructor(fileExplorer: Subject){
this.subject = fileExplorer;
fileExplorer.registerObserver(this);
}

  update(fileName: string) {
    console.log('I need to update my Editor with ' + 'fileName');
  }
}

Solution

  • Angular is trying to instatiate and inject the object fileExplorer to the YComponent. But an interface cannot be instatiated. You have to create an injectable class that extends Subject interface, and inject that to your component. In the video you can see that Workstation extends Subject.


    If you want to communicate between components, there are 3 ways in my knowledge:

    1. Passing the reference of one component to another
    2. Communication through parent component
    3. Communication through Service

    Here's an article