Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular 2 getting hold of an element in Angular 2 for use in Material design lite

I want to use the Material Design Lite snackbar in Angular 2.

I tried to get hold of the Element in my template as the following:

My template

 <test>
     <div id="child1"> child1 <div id="child2">
      <div id="child2"> child2 <div id="child2">
       <div id="toast_error"> Error message </div>
      </div>
     </div>
    </div>
</test>

In my component file

constructor(private el:ElementRef){}

ngOnInit(){
        this.show_error("something");
    }
show_error(err){
        var snackbarContainer = this.el.nativeElement.querySelector("#toast_error")
        var data = {
            message: 'Button color changed.',
            timeout: 2000,
            actionText: 'Undo'
        };

        snackbarContainer.MaterialSnackbar.showSnackbar(data);
    }

I get the folowing error message. How do I get hold of the element with id toast_error

EXCEPTION: TypeError: Cannot read property 'MaterialSnackbar' of null in [null]

PS: I have checked that this.el.nativeElement does give me the correct reference

Edit

Following the answers and comments, I can now get hold of the element by using the same code inside ngAfterViewInit. However, I can't get the snackbar to work. Following is the updated code.

In my component file

   constructor(private el:ElementRef){}


    ngAfterViewInit(){
            var snackbarContainer = this.el.nativeElement.querySelector("#toast_error")
            var data = {
                message: 'Button color changed.',
                timeout: 2000,
                actionText: 'Undo'
            };

            console.log(snackbarContainer.MaterialSnackbar); //prints undefined
            //snackbarContainer.MaterialSnackbar.showSnackbar(data);
        }

The console.log() command prints undefined. I have made sure that the material.min.js is loaded and checked the file, it does include MaterialSnackbar. How should I debug this?

like image 846
kosta Avatar asked Feb 24 '16 06:02

kosta


2 Answers

I solved the problem by placing the code in ngAfterViewInit() and also calling the upgradeElement as below:

constructor(private el:ElementRef){} 

ngAfterViewInit(){
    window.componentHandler.upgradeAllRegistered();
    var snackbarContainer =         this.el.nativeElement.querySelector("#toast_error")
                    var data = {
                        message: 'Button color changed.',
                        timeout: 2000,
                        actionText: 'Undo'
                    };                           
    snackbarContainer.MaterialSnackbar.showSnackbar(data);
                    }
like image 81
kosta Avatar answered Oct 13 '22 21:10

kosta


If you need direct access to DOM element then have the ElementRef injected:

constructor(ref: ElementRef) ...

And then access the DOM element using:

ref.nativeElement

See here for further information.

Then instead of OnInit, try with AfterViewInit, to make sure the DOM is initialized before running the DOM query -> see here.

like image 43
Angular University Avatar answered Oct 13 '22 20:10

Angular University