Vasilis Greece
Vasilis Greece

Reputation: 907

Angular - On resize change html element

I am using Angular 5. What I am trying to do is a responsive side navigation bar. When the window width changes I need some events to apply (css, content etc). In my example I want to change the inner Html - text, when the window width is below of 1080 pixels.

I tried three ways. By javascript and ng-model but nothing.

Html:

<div id="nav-left">
    <mat-list>
     <mat-list-item><a id="elp1" [routerLink]="['/']" fragment="intro-text" ng-model="innerHtml"> Welcome </a></mat-list-item>
     <mat-list-item><a id="elp2" [routerLink]="['/']" fragment="introduction"> Introduction </a></mat-list-item>
     ...
    </mat-list>
</div> 

Component (first way):

@HostListener('window:resize', ['$event'])
    onResize(event?) {      
      this.screenWidth = window.innerWidth;
      let bgScreen = true;
      let smScreen = true;
      if(this.screenWidth < 1080 && smScreen){
        document.getElementById("elp1").innerHTML = "New";

        smScreen = false; 
        bgScreen = true;

      }else if(this.screenWidth >= 1080 && bgScreen){
        document.getElementById("elp1").innerHTML = " Welcome ";

        bgScreen = false;
        smScreen = true;        
      }else{
        console.log('problem');
      }
    }

In this case I get a console error:

Uncaught (in promise): TypeError: Cannot set property 'innerHTML' of null

Component (second way):

@HostListener('window:resize', ['$event'])
        onResize(event?) {      
          this.screenWidth = window.innerWidth;

          if(this.screenWidth < 1080){
            let element = <HTMLInputElement>document.getElementById("elp1");
            element.value = "New";

          }else if(this.screenWidth >= 1080){
            let element = <HTMLInputElement>document.getElementById("elp1");
            element.value = "Welcome";      
          }else{
            console.log('problem');
          }
        }

With the error:

Uncaught (in promise): TypeError: Cannot set property 'value' of null

Component (third way & ng-model):

@HostListener('window:resize', ['$event'])
            onResize(event?) {      
              this.screenWidth = window.innerWidth;

              if(this.screenWidth < 1080){
                let innerHtml :string = "New";

              }else if(this.screenWidth >= 1080){
                let innerHtml :string = "Welcome";      
              }else{
                console.log('problem');
              }
            }

With no errors but it doesn't work.

1) The first problem are the above errors. 2) and secondly as you see in the "first way" example I tried to add flags trigger effects and realized that didn't worked either. Variables "bgScreen" and "smScreen" are always true. I put those for a better coding flow.

I don't want to use jQuery. Only typescript or with angular (ng-model) way. Any suggestions?

Upvotes: 1

Views: 3399

Answers (2)

Martin Parenteau
Martin Parenteau

Reputation: 73721

I recommend using data binding to set the content of the link:

<div id="nav-left">
  <mat-list>
    <mat-list-item><a [routerLink]="['/']" fragment="intro-text"> {{introText}} </a></mat-list-item>
     ...
  </mat-list>
</div>

The public property introText can be modified when the window is resized:

introText = "Welcome";

@HostListener("window:resize", ["$event"])
onResize(event) {      
  this.introText = window.innerWidth < 1080 ? "New" : "Welcome";
}

or, as an alternative, you could define introText as a getter (not handling the resize event):

get introText(): string {
  return window.innerWidth < 1080 ? "New" : "Welcome";
}

Upvotes: 1

ngChaitanya
ngChaitanya

Reputation: 435

To get element instead of using document.getElementById("elp1") try ViewChild of angular if child element of component, or ElementRef for component itself. As here it looks child element of Component you could use ViewChild

You will get the access to element in angular component.

so now your HTML would be

<mat-list-item><a #elp1 [routerLink]="['/']" fragment="intro-text"> Welcome </a></mat-list-item>

and in @component

import { ViewChild} from '@angular/core';
.
.
@ViewChild('elp1') link;

//And assign values like below now.
this.link.nativeElement.innerHTML = "New";

Hope this helps.

Upvotes: 0

Related Questions