Search code examples
angulartypescript1.8reflect-metadata

Can we iterate over all EventEmitter decorated with @Output() in Angular 2


What I want to achieve is for a given component instance I want to iterate over all the EventEmitter decorated with @Output.

For e.g.

my-component

   @Component({
     moduleId: module.id,
     selector: "my-component",
     template: "<h1>My Component!!"
   })
   export class MyComponent{ 
     @Output() emitter1: EventEmitter<any> = new EventEmitter<any>();
     @Output() emitter2: EventEmitter<any> = new EventEmitter<any>();
   }

so lets say I am loading this component dynamically like below,

   this._cr.resolveComponent(MyComponent).then(cmpFactory => {
        this.testComponentContainer.clear();
        let instance: any = this.testComponentContainer.createComponent(cmpFactory).instance;

        // Here I want to iterate over EventEmitter dynamically
        // So that I may bind to both emitter1 and emitter2
    });

Can i do this? Thanks in advance!!


Solution

  • You could look at the propMetadata metadata to find out the decorated output.

    Here is a sample:

    this._cr.resolveComponent(MyComponent).then(cmpFactory => {
        this.testComponentContainer.clear();
        let instance: any = this.testComponentContainer.createComponent(cmpFactory).instance;
    
        var propMetadata = Reflect.getMetadata('propMetadata', MyComponent);
        var outputs = propMetadata.filter(metadata => {
          return (metadata instanceof OutputMetadata);
        });
    
        outputs.forEach(output => {
          output.subscribe(event => {
            // handle event
          });
        });
    
        // Here I want to iterate over EventEmitter dynamically
        // So that I may bind to both emitter1 and emitter2
    });
    

    Update by Madhu Ranjan There are issues with above code, However it hinted me to use it correctly like below,

       this._cr.resolveComponent(componentToTest).then(cmpFactory => {
            this.testComponentContainer.clear();
            let instance: any =   this.testComponentContainer.createComponent(cmpFactory).instance;
    
            let propMetadata: any = Reflect.getMetadata('propMetadata', componentToTest);
            let outputs: any = [];
    
            for (let key in propMetadata) {
                if (propMetadata.hasOwnProperty(key)) {
                    if (propMetadata[key].length > 0) {
                        let _hasOutput = propMetadata[key].filter(metadata => {
                            return (metadata instanceof OutputMetadata);
                        });
    
                        if (_hasOutput && _hasOutput.length > 0) {
                            outputs.push(key);
                        }
                    }
                }
            }
    
            outputs.forEach(output => {
                instance[output].subscribe(event => {
                    // Logic to use event data..
                });
            });
        });