5
votes

I am trying to create a custom Spinner component for my App, So I have created

spinner.component.ts

export class SpinnerComponent implements AfterViewInit {

    @ViewChild("spinner") spinner: ElementRef;

    constructor() { }

    ngAfterViewInit(): void {
        this.spinner.nativeElement.style.display = "none";
    }

    public show = (): void => { this.spinner.nativeElement.style.display = "block"; };

    public hide = (): void => { this.spinner.nativeElement.style.display = "none"; };

}

spinner.component.ts

<img #spinner src="assets/images/dotSpinner.gif" class="loading"/>

And I'm trying to control this spinner in my other components, like

sample.component.ts

import { SpinnerComponent } from "../spinner/spinner.component";

export class SimpleComponent {

    private spinner: SpinnerComponent = new SpinnerComponent();

    constructor() {}

    actionHandler = (data: any): void => {
        this.spinner.show();
        this.clientActionService.subscribe(
            data => {
                this.spinner.hide();
                this.clientAction = data;
            },
            err => {
                this.spinner.hide();
            }
        );
    }

}

But I'm getting error ERROR TypeError: Cannot read property 'nativeElement' of undefined at SpinnerComponent.show

3
You should not create component instance manually. Either use query(ViewChild,ContentChild) or DI mechanism as suggested above. - yurzui
I tried it, but I'm getting error like ERROR Error: StaticInjectorError(AppModule)[SimpleComponent -> SpinnerComponent]: StaticInjectorError(Platform: core)[SimpleComponent -> SpinnerComponent]: NullInjectorError: No provider for SpinnerComponent! - SjVnyk
I did registered it on app.module.ts - SjVnyk

3 Answers

1
votes

spinner.component.ts // html code

 <img *ngIf="isShowSpinner" src="assets/images/dotSpinner.gif" class="loading"/>

 <button (click)="show()"> Show </button>
 <button (click)="hide()"> Hide </button>

spinner.component.ts //typescript code

public isShowSpinner: boolean = false;
constructor() { }

public show() { this.isShowSpinner = true; }    
public hide() { this.isShowSpinner = false; }

Please try this.

0
votes

If you want workaround then

<img
    [ngStyle]="{'display': displayVal}"
    src="assets/images/dotSpinner.gif"
    class="loading"/>

Typescript code

display = "none";
public show = (): void => { this.displayVal = "block"; };
public hide = (): void => { this.displayVal = "none"; };
0
votes

Use forwardRef

forwardRef is used when the token which we need to refer to for the purposes of DI is declared, but not yet defined. It is also used when the token which we use when creating a query is not yet defined.

   import { SpinnerComponent } from "../spinner/spinner.component";   
    export class SimpleComponent {   
        constructor(constructor(@Inject(forwardRef(() => SpinnerComponent )) private ref:any)) {}

        actionHandler = (data: any): void => {
            this.ref.show();
            this.clientActionService.subscribe(
                data => {
                    this.ref.hide();
                    this.clientAction = data;
                },
                err => {
                    this.ref.hide();
                }
            );
        }

    }